wdmtxyh123 6 months ago
parent dd6759ddcb
commit ad08e20fda

539
Car.py

@ -1,534 +1,19 @@
from enum import Enum
import time
import re
import os
import logging
class Car:
def __init__(self, license_plate, model, color):
Model = Enum('Model', ("小汽车", "小卡", "中卡", "大卡"))
Color = Enum('Color', ("白色", "黑色", "灰色", "蓝色", "红色", "黄色"))
unit_price = 5 # 每小时单价为5元
class Car(object): # ParkManage
def __init__(self, parknum, carnum, model, color, intime=None):
# super(Car, self).__init__()
self.parknum = parknum
self.carnum = carnum
self.license_plate = license_plate
self.model = model
self.color = color
self.intime = intime
def __setitem__(self, key, value):
self.__dict__[key] = value
def __getitem__(self, key):
return self.__dict__[key]
def __str__(self):
return "%4s %-8s %-6s %-s %s" % \
(self.parknum, self.carnum, self.model.name, self.color.name, self.intime)
class ParkManage(object):
def __init__(self, max_car=150):
self.max_car = max_car
self.carlist = []
# self.carnum = len(self.carlist)
def check_empty(self, model=1):
"""
查找空闲车位model=1默认按小汽车查找
:return:{list}空闲车位号列表
"""
if model == 1:
# t_num = [parkedCar["parknum"] for parkedCar in self.carlist]
"""
t_list = []
for i in range(self.max_car):
if i not in t_num:
t_list.append(i)
return t_list
"""
# return [i for i in range(self.max_car) if i not in t_num]
return [i for i in range(self.max_car) if i not in
[parkedCar["parknum"] for parkedCar in self.carlist]]
def inquire_empty(self):
"""
查询空闲车位调用即可进行输出
:return: None
"""
t_i = 0
for t_empty in self.check_empty():
print("%3s " % t_empty, end='')
t_i += 1
if len(self.check_empty()) > 15 and t_i % 15 == 0: # 每15个一行
print('')
def check_car_num(self, carnum):
"""
基于正则表达式判断车牌号是否合法合法为True
:return:{bool}True/False
"""
# return True # TODO DEBUG
car_license = re.compile(u"^[\u4e00-\u9fa5][A-Z][A-Z0-9]{5}$") # e.g.: 苏BCD123
if car_license.match(carnum):
return True
else:
return False
def park(self, isAdmin):
"""
输入车辆信息停车管理员isAdmin==1时询问是否继续停车
:return:None
"""
if len(self.carlist) >= self.max_car:
print("对不起,当前车库已满!")
return None
while True:
print('当前空闲车位如下:')
self.inquire_empty()
print('')
# 变量初始化
flag_right_input = False
flag_error = 0 # 清除错误flag
temp_parknum = None
temp_carnum = None
temp_color = None
temp_model = None
try:
temp_parknum = int(input('请输入所停车位:'))
temp_carnum = input('请输入车牌号:')
temp_model = int(input('请输入车型序号1小汽车, 2小卡, 3中卡, 4大卡:'))
temp_color = int(input('请输入车辆颜色序号1白色, 2黑色, 3灰色, 4蓝色, 5红色, 6黄色:'))
# 以下为输入信息是否有效的判断
if 0 <= temp_parknum <= self.max_car: # 判断车位是否在合理范围内
if 1 <= temp_model <= 4:
temp_model = Model(temp_model) # 转化为Model枚举类型
if 1 <= temp_color <= 6:
temp_color = Color(temp_color) # 转化Color枚举类型
if self.check_car_num(temp_carnum): # 判断车牌号是否有效
for parkedCar in self.carlist:
if parkedCar.parknum == temp_parknum: # 判断车位是否已被占用
flag_error = 1
break
elif parkedCar.carnum == temp_carnum: # 判断车牌是否已重复
flag_error = 2
break
else:
flag_right_input = True # 以上判断均通过
"""
else:
error_input = 3
else:
error_input = 4
else:
error_input = 5
"""
except Exception as e:
# logging.exception(e) # for debug
flag_right_input = False # 输入类型错误
# error_input = 6
finally:
# if error_input != 0:
if not flag_right_input:
if flag_error == 1:
print('当前车位已被占用!')
elif flag_error == 2:
print('车牌号重复!')
else:
print("输入错误!")
retry_choice = input('按<F>键返回主菜单,按其他任意键重试')
if retry_choice == 'F' or retry_choice == 'f':
return None # 返回主菜单
else:
os.system('cls') # 清屏
else:
# 通过各项判断,下面新增车辆
temp_car = Car(temp_parknum, temp_carnum, temp_model, temp_color)
temp_car["intime"] = time.ctime() # 调用当前时间
self.carlist.append(temp_car)
print("%s 停车入库成功!" % temp_carnum)
if not isAdmin: # 用户返回主菜单
print('按任意键返回主菜单......')
os.system("pause")
return None
if isAdmin: # 管理员询问是否继续新增车辆
while True:
continue_choice = input("YN继续新增车辆")
if continue_choice == 'Y' or continue_choice == 'y':
os.system('cls') # 清屏
break
elif continue_choice == 'N' or continue_choice == 'n':
return None
else:
print('输入错误,请重试!')
"""
def add_car(self, car):
# 从car新增车辆到carlist中
# if self.check_car(car) is not None:
# print("车辆已存在,请重试!")
# else:
car["intime"] = time.ctime() # 调用当前时间
self.carlist.append(car)
print("%s 停车入库成功!" % car.carnum)
"""
def display(self, carlist=None):
"""
显示车辆信息
:param:{list}carlist, 默认为self.carlist
:return:None
"""
if carlist is None:
carlist = self.carlist
if len(self.carlist) == 0:
print("停车场内暂无车辆。")
return None
print("车位 车牌号 车型 颜色 入场时间 ")
i = 0
for parkedCar in carlist:
print(parkedCar)
i += 1
if len(carlist) > 10 and i % 10 == 0: # 超过10辆车则每10辆一页
print("按任意键查看下一页......")
os.system("pause")
print("车位 车牌号 车型 颜色 入场时间 ")
# os.system('pause')
def check_car(self, keyword, sort=1):
"""
用于查找车辆默认sort=1,按照车位查找若存在则返回满足条件的车辆信息
:param:keyword关键词sort查找方式
:return:{class Car}/{list}
"""
if sort == 1: # 按车位
for parkedCar in self.carlist:
if parkedCar.parknum == keyword:
return parkedCar
elif sort == 2: # 按车牌
for parkedCar in self.carlist:
if parkedCar.carnum == keyword:
return parkedCar
elif 3 <= sort <= 4:
if sort == 3: # 按车型
key = "model"
elif sort == 4: # 按颜色
key = "color"
else:
return None
t_list = []
for parkedCar in self.carlist:
if parkedCar[key] == keyword:
t_list.append(parkedCar)
return t_list
elif sort == 5: # TODO 按入场时间
# (developing)
pass
else:
return None
def inquire(self, choice=-1):
"""
查询信息
复用于取车的查找修改信息的查找
Developing:按照入场时间查询多少时间内
:param choice:查询方式选择默认为-1.
:return:None/{class Car}parkedCar
"""
# choice = -1 # DEBUG
while choice < 0 or choice > 6:
print("""
1)空闲车位查询
--车辆信息查询--
2)按车位查询车辆
3)按车牌查询车辆
4)按车型查询车辆
5)按颜色查询车辆
6)按入场时间查询(developing)
---------------------------
0)返回主菜单
""")
try:
choice = int(input("请输入操作码:"))
except Exception:
print("错误操作码,请重试!")
continue
if choice < 0 or choice > 6:
print("错误操作码,请重试!")
if choice == 0:
return None # 返回主菜单
# 空闲车位查询:
elif choice == 1:
if len(self.carlist) >= self.max_car:
print("对不起,当前车库已满!")
return None
else:
print('空闲车位如下:')
self.inquire_empty()
print('') # 多空一行
else:
if len(self.carlist) == 0:
print("停车场内暂无车辆。")
return None
try:
# 按车位查询车辆:
if choice == 2:
keyword = int(input("请输入车位号:"))
t_result = self.check_car(keyword, sort=1)
if t_result:
print("车位 车牌号 车型 颜色 入场时间 ")
print(t_result)
return t_result
else:
print("停车场中无此车辆。")
# 按车牌查询车辆:
elif choice == 3:
keyword = input("请输入车牌号:")
t_result = self.check_car(keyword, sort=2)
if t_result:
print("车位 车牌号 车型 颜色 入场时间 ")
print(t_result)
return t_result
else:
print("停车场中无此车辆。")
# 按车型查询车辆:
elif choice == 4:
keyword = Model(int(input("请输入车辆的车型1小汽车, 2小卡, 3中卡, 4大卡")))
t_result = self.check_car(keyword, sort=3)
if t_result:
self.display(t_result)
else:
print("停车场中无此车型车辆。")
# 按颜色查询车辆:
elif choice == 5:
keyword = Color(int(input("请输入车辆的颜色1白色, 2黑色, 3灰色, 4蓝色, 5红色, 6黄色")))
t_result = self.check_car(keyword, sort=4)
if t_result:
self.display(t_result)
else:
print("停车场中无此颜色车辆。")
# 按入场时间查询:
elif choice == 6:
# TODO (developing) 按入场时间查询
pass
"""
keyword = input("请输入入场时间:")
t_result = self.check_car(keyword, sort=5)
if t_result:
print(t_result)
else:
print("停车场中无此车辆。")
"""
else:
pass
except Exception as e: # 输入异常处理
# logging.exception(e) # DEBUG
print("输入错误,按任意键返回......")
return None
def pickup(self):
"""
取车
:return:None
"""
if len(self.carlist) == 0:
print("停车场内暂无车辆。")
return None
# 变量初始化
exit_car = None
inquire_choice = -1
while inquire_choice < 0 or inquire_choice > 2:
try:
print("-----------取车-----------")
inquire_choice = int(input("1)按车位查找\n2)按车牌号查找\n0)返回主菜单\n\n请输入操作码:"))
except:
continue
if inquire_choice == 0: # 返回主菜单
return None
elif inquire_choice == 1: # 按车位
exit_car = self.inquire(choice=2)
elif inquire_choice == 2: # 按车牌号
exit_car = self.inquire(choice=3)
if exit_car is None:
return None
exit_choice = input("确定请输入“Y”其他任意输入返回主菜单")
if exit_choice == 'Y' or exit_choice == 'y':
exit_time = time.ctime()
park_time = time.mktime(time.strptime(exit_time)) - time.mktime(time.strptime(exit_car.intime))
m, s = divmod(park_time, 60)
h, m = divmod(m, 60)
str_time = "%02d:%02d:%02d" % (h, m, s) # 得到时分秒字符串
global unit_price
price = h * unit_price
print("车牌号:%s \n停车时长:%s\n请交费%3d" % (exit_car.carnum, str_time, price))
self.carlist.remove(exit_car)
os.system("pause") # 预留之后完善计费功能
print("结算成功,欢迎您再次光临!")
else:
return None
def edit(self):
"""
编辑车辆信息
:return:None
"""
if len(self.carlist) == 0:
print("停车场内暂无车辆。")
return None
# 变量初始化
edit_car = None
inquire_choice = -1
while inquire_choice < 0 or inquire_choice > 2:
try:
print("-----车辆信息编辑-----")
inquire_choice = int(input("1)按车位查找\n2)按车牌号查找\n0)返回主菜单\n\n请输入操作码:"))
except:
continue
if inquire_choice == 0: # 返回主菜单
return None
elif inquire_choice == 1: # 按车位
edit_car = self.inquire(choice=2)
elif inquire_choice == 2: # 按车牌号
edit_car = self.inquire(choice=3)
if edit_car is None:
return None
edit_choice = input("确定请输入“Y”其他任意输入返回主菜单")
if edit_choice == 'Y' or edit_choice == 'y':
index = self.carlist.index(edit_car) # 获取索引
while True:
try:
flag_right = False # right flag
change_choice = input(
"\n1)车位号\n2)车牌号\n3)车型\n4)车颜色\n5)入场时间\n0)不修改返回主菜单\n\n请输入您要修改的信息序号:")
if change_choice == '0':
return None
elif change_choice == '1':
new_info = int(input("请输入新的车位号:"))
if 0 <= new_info <= self.max_car: # 在范围内
for parkedCar in self.carlist:
if parkedCar.parknum == new_info: # 判断车位是否已被占用
print(" %d号车位已被占用!" % new_info)
break
else:
self.carlist[index]["parknum"] = new_info
flag_right = True
print("车位号修改成功!")
# break
elif change_choice == '2':
new_info = input("请输入新的车牌号:")
if self.check_car_num(new_info): # 判断车牌号是否有效
for parkedCar in self.carlist:
if parkedCar.carnum == new_info: # 判断车牌是否已重复
print("车牌号重复!")
break
else:
self.carlist[index]["carnum"] = new_info
flag_right = True
print("车牌号修改成功!")
# break
elif change_choice == '3':
new_info = int(input("请输入新的车型1小汽车, 2小卡, 3中卡, 4大卡:"))
if 1 <= new_info <= 4:
new_info = Model(new_info) # 转化为Model枚举类型
self.carlist[index]["model"] = new_info
flag_right = True
print("车型修改成功!")
elif change_choice == '4':
new_info = int(input("请输入新的车颜色1白色, 2黑色, 3灰色, 4蓝色, 5红色, 6黄色"))
if 1 <= new_info <= 6:
new_info = Color(new_info) # 转化Color枚举类型
self.carlist[index]["color"] = new_info
flag_right = True
print("颜色修改成功!")
elif change_choice == '5':
new_info = input("请输入新的入场时间:(参考格式2019.3.4 12:00:00)")
print("DEVELOPING...")
# TODO 修改入场时间
pass
break
else:
pass
except:
print("输入错误,请重试!")
continue
if flag_right:
break
else:
print("请重试!")
continue
else:
return None
def statistics(self):
"""
统计车辆信息
:return:None
"""
print("""
本停车场总车位数{total:3d}
当前已驶入车辆数{exist:3d} 空闲车位数{empty:3d}
-----------------------------------------------
""".format(total=self.max_car, exist=len(self.carlist), empty=self.max_car - len(self.carlist)),
end='')
# 按车型、颜色统计车辆信息
cnt_model = [0, 0, 0, 0]
cnt_color = [0, 0, 0, 0, 0, 0]
if len(self.carlist) != 0:
for parkedCar in self.carlist:
cnt_model[parkedCar.model.value - 1] += 1
cnt_color[parkedCar.color.value - 1] += 1
print("""
* 按车型统计
小汽车 {:3d}, 小卡 {:3d}, 中卡 {:3d}, 大卡 {:3d}
* 按颜色统计
白色 {:3d}, 黑色 {:3d}, 灰色 {:3d}
蓝色 {:3d}, 红色 {:3d}, 黄色 {:3d}
""".format(cnt_model[0], cnt_model[1], cnt_model[2], cnt_model[3],
cnt_color[0], cnt_color[1], cnt_color[2],
cnt_color[3], cnt_color[4], cnt_color[5], ), end='')
if len(self.carlist) == 0:
print("""
-----------------------------------------------
""")
else:
# TODO 按入场时间统计
print("""
* 按入场时间统计
正在开发中 Developing...
-----------------------------------------------""")
"""返回车辆的字符串表示"""
return f"车牌号: {self.license_plate}, 车型: {self.model}, 颜色: {self.color}"
# TODO 车辆信息按顺序输出
def update_info(self, license_plate=None, model=None, color=None):
# choice = input("""
# 1)按车位排序 2)按入场时间排序
# 请输入操作码(其他任意输入返回主菜单):""")
# if choice == '1':
# pass
# temp_carlist = []
# for parkedCar in self.carlist:
# pass
#
# self.display(temp_carlist)
# elif choice == '2':
# pass
# else:
# return None
#
if license_plate is not None:
self.license_plate = license_plate
if model is not None:
self.model = model
if color is not None:
self.color = color

@ -1,2 +0,0 @@
import tkinter as tk
import tkinter.messagebox

78
IO.py

@ -1,78 +0,0 @@
import multiprocessing as mp
from Car import Car, Model, Color
def load_from_file(park, filename=r"cars.csv"):
"""
从文件中读取车辆信息
:param park:停车场实例
:param filename:文件名
:return: {class ParkManage}park, {int}cnt:导入成功计数
"""
cnt = 0 # counter
try:
with open(filename, 'r+') as fp:
while True:
temp_car = fp.readline()
if temp_car == '':
break
else:
items = list(temp_car.strip().split(','))
car = Car(int(items[0]), items[1], Model(int(items[2])), Color(int(items[3])), items[4])
park.carlist.append(car)
cnt += 1
except Exception:
print('File loaded error!')
return park, cnt
def load_new_file(park):
"""
从新文件中加载记录成功返回加载后的park否则返回原来的park
注意此处暂未考虑重复记录及记录的有效性
:param park:停车场实例
:return: {class ParkManage}park
"""
filename = input('请输入导入的文件名(请勿重复导入):')
if filename == '':
print('文件名不能为空!')
return park
elif filename == 'cars.csv':
print('请勿导入重复文件!')
return park
else:
temp_park, cnt_success = load_from_file(park=park, filename=filename)
if cnt_success > 0:
print('成功导入 %d 条记录。' % cnt_success)
return temp_park
else:
print('导入失败!')
return park
def write_to_file(park, filename=r"cars.csv"):
"""
将车辆信息写入文件
:param park:停车场实例
:param filename:文件名
:return: None
"""
try:
with open(filename, 'w+') as file:
if len(park.carlist) == 0:
pass
for parkedCar in park.carlist:
file.write('{},{},{},{},{}\n'.format(parkedCar.parknum, parkedCar.carnum, parkedCar.model.value,
parkedCar.color.value, parkedCar.intime))
except Exception:
print('File wrote error!')
def realtimeIO():
"""
TODO 实时读写文件
思路子进程每隔一段时间检查一次self.carlist发现改动则更新文件
:return: None
"""
pass

@ -1,21 +0,0 @@
class Member:
def __init__(self, member_id, name, license_plate, points):
self.member_id = member_id
self.name = name
self.license_plate = license_plate
self.points = points
def add_points(self, points):
self.points += points
# 更新数据库中的会员积分
# ...
def redeem_points(self, points_to_redeem):
if points_to_redeem <= self.points:
self.points -= points_to_redeem
# 更新数据库中的会员积分
# ...
return True
else:
print("Insufficient points.")
return False

@ -0,0 +1,201 @@
import mysql.connector
from mysql.connector import Error
from tkinter import messagebox
from Car import Car
class ParkManage:
def __init__(self, host="localhost", user="root", password="root", database="sys", user_gui=None):
"""初始化数据库连接"""
self.conn = mysql.connector.connect(
host="localhost",
user="root",
password="root",
database="sys"
)
self.cursor = self.conn.cursor()
self.create_tables()
self.user_gui = user_gui # 添加一个可选参数用于Tkinter根窗口
def create_tables(self):
"""创建必要的数据库表"""
try:
self.cursor.execute("""
CREATE TABLE IF NOT EXISTS parked_cars (
id INT AUTO_INCREMENT PRIMARY KEY,
license_plate VARCHAR(255) NOT NULL UNIQUE,
parked_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
picked_up_time TIMESTAMP NULL
);
""")
self.conn.commit()
except Error as e:
messagebox.showerror("数据库错误", f"创建表失败: {e}")
def park(self, license_plate):
"""处理停车逻辑并存储到数据库"""
try:
query = "INSERT INTO parked_cars (license_plate) VALUES (%s)"
values = (license_plate,)
self.cursor.execute(query, values)
self.conn.commit()
return True
except mysql.connector.IntegrityError: # 车牌号已存在
return False
except Error as e:
messagebox.showerror("数据库错误", f"停车操作时发生错误: {e}")
return False
def pickup(self, license_plate):
"""处理取车逻辑,更新数据库记录"""
try:
# 更新取车时间
query = "UPDATE parked_cars SET picked_up_time = CURRENT_TIMESTAMP WHERE license_plate = %s AND picked_up_time IS NULL"
values = (license_plate,)
self.cursor.execute(query, values)
if self.cursor.rowcount > 0:
self.conn.commit()
return True
else:
messagebox.showinfo("取车失败", f"车牌号{license_plate}的车辆未找到或已取走。")
return False
except Error as e:
messagebox.showerror("数据库错误", f"取车操作时发生错误: {e}")
return False
# 其他方法如查询、编辑、统计等可以根据需要类似地实现
def query_car_info(self, license_plate):
"""根据车牌号查询车辆停放信息"""
try:
query = """
SELECT
license_plate,
parked_time,
picked_up_time
FROM
parked_cars
WHERE
license_plate = %s
"""
values = (license_plate,)
self.cursor.execute(query, values)
car_info = self.cursor.fetchone()
if car_info:
# 格式化输出信息
parked_time_str = car_info[1].strftime('%Y-%m-%d %H:%M:%S')
picked_up_time_str = "尚未取车" if car_info[2] is None else car_info[2].strftime('%Y-%m-%d %H:%M:%S')
message = f"车牌号: {car_info[0]}\n停放时间: {parked_time_str}\n取车时间: {picked_up_time_str}"
messagebox.showinfo("车辆信息", message)
else:
messagebox.showinfo("查询结果", "未找到该车牌号的车辆信息。")
except Error as e:
messagebox.showerror("查询错误", f"查询车辆信息时发生错误: {e}")
def display_all_cars_info(self):
"""显示所有车辆的停放信息"""
try:
query = """
SELECT
license_plate,
parked_time,
picked_up_time
FROM
parked_cars
"""
self.cursor.execute(query)
all_cars_info = self.cursor.fetchall()
if all_cars_info:
# 遍历所有车辆信息并格式化输出
all_cars_message = "\n\n".join([
f"车牌号: {car[0]}\n"
f"停放时间: {car[1].strftime('%Y-%m-%d %H:%M:%S')}\n"
f"取车时间: {'未取车' if car[2] is None else car[2].strftime('%Y-%m-%d %H:%M:%S')}"
for car in all_cars_info
])
messagebox.showinfo("所有车辆信息", all_cars_message)
else:
messagebox.showinfo("信息提示", "当前停车场内没有车辆信息。")
except Error as e:
messagebox.showerror("显示错误", f"显示所有车辆信息时发生错误: {e}")
def edit_car_pickup_time(self, license_plate):
"""编辑车辆的取车时间"""
try:
# 查询指定车牌号的车辆是否存在
check_query = """
SELECT COUNT(*)
FROM parked_cars
WHERE license_plate = %s
"""
self.cursor.execute(check_query, (license_plate,))
car_exists = self.cursor.fetchone()[0]
if car_exists:
# 弹出对话框让用户输入新的取车时间
new_picked_up_time_str = simpledialog.askstring("编辑取车时间",
"请输入新的取车时间YYYY-MM-DD HH:MM:SS:",
initialvalue="2023-04-01 14:00:00")
if new_picked_up_time_str:
try:
# 尝试将输入的字符串转换为datetime对象
from datetime import datetime
new_picked_up_time = datetime.strptime(new_picked_up_time_str, '%Y-%m-%d %H:%M:%S')
except ValueError:
messagebox.showerror("输入错误", "请输入正确的日期时间格式!")
return
# 更新数据库中的取车时间
update_query = """
UPDATE parked_cars
SET picked_up_time = %s
WHERE license_plate = %s
"""
self.cursor.execute(update_query, (new_picked_up_time, license_plate))
self.connection.commit() # 提交事务
messagebox.showinfo("更新成功", f"车牌号为{license_plate}的车辆取车时间已更新。")
else:
messagebox.showinfo("取消操作", "未输入取车时间,操作已取消。")
else:
messagebox.showinfo("查询结果", "未找到该车牌号的车辆信息。")
except Error as e:
messagebox.showerror("编辑错误", f"编辑车辆取车时间时发生错误: {e}")
def count_parked_cars(self):
"""统计当前停在停车场的车辆总数"""
query = "SELECT COUNT(*) FROM parked_cars"
self.cursor.execute(query)
parked_count = self.cursor.fetchone()[0]
return parked_count
def count_empty_slots(self, total_slots):
"""计算空闲车位数"""
parked_count = self.count_parked_cars()
empty_slots = total_slots - parked_count
return empty_slots
def most_frequent_parking_time(self):
"""
分析并返回最频繁的停车时段
这里简化处理实际应用中可能需要更复杂的SQL查询来统计时段
"""
query = """
SELECT
HOUR(parked_time) AS hour,
COUNT(*) AS frequency
FROM parked_cars
GROUP BY hour
ORDER BY frequency DESC
LIMIT 1
"""
self.cursor.execute(query)
most_frequent_hour, _ = self.cursor.fetchone()
return f"最频繁的停车时段是第{most_frequent_hour}小时"
def close_connection(self):
"""关闭数据库连接"""
if self.conn.is_connected():
self.cursor.close()
self.conn.close()

@ -1,229 +0,0 @@
import tkinter as tk
from tkinter import messagebox, simpledialog
from datetime import datetime
import mysql.connector
conn = mysql.connector.connect(
host="localhost",
user="root",
password="root",
database="sys"
)
class ParkingLotManager:
def __init__(self):
self.conn = mysql.connector.connect(
host="localhost",
user="root",
password="root",
database="sys"
)
self.cursor = self.conn.cursor()
# 初始化时从数据库加载定价规则
self.load_pricing_rules_from_db()
self.parked_vehicles = {} # 本地缓存,用于快速查询
def load_parked_vehicles_from_db(self):
"""从数据库加载已停车辆"""
self.cursor.execute("SELECT license_plate, vehicle_type, entry_time FROM parked_vehicles")
parked_data = self.cursor.fetchall()
for plate, vehicle_type, entry_time in parked_data:
self.parked_vehicles[plate] = {
'vehicle': Vehicle(plate, vehicle_type),
'entry_time': datetime.strptime(entry_time, "%Y-%m-%d %H:%M:%S")
}
# 添加一个新方法用于初始化App时加载数据
def initialize_data_on_login(self):
self.load_parked_vehicles_from_db()
# 在ParkingSystemApp的__init__方法中调用加载数据的方法
def open_main_system(parking_manager):
main_system_window = tk.Toplevel(login_window)
main_system_window.title("停车场管理系统 - 主功能")
# 在创建ParkingSystemApp实例前先初始化数据
parking_manager.initialize_data_on_login()
app = ParkingSystemApp(main_system_window, parking_manager)
main_system_window.protocol("WM_DELETE_WINDOW", lambda: [main_system_window.destroy(), login_window.destroy()])
def __init__(self, master, parking_manager):
# ...其他初始化代码...
parking_manager.load_parked_vehicles_from_db()
self.update_ui_vehicles()
def park_vehicle(self, vehicle):
# 除了现有逻辑,还需要在数据库中记录入场时间
sql = "INSERT INTO parked_vehicles (license_plate, vehicle_type, entry_time) VALUES (%s, %s, %s)"
val = (vehicle.get_license_plate(), vehicle.get_vehicle_type(), datetime.now())
self.cursor.execute(sql, val)
self.conn.commit()
self.parked_vehicles[vehicle.get_license_plate()] = {'vehicle': vehicle, 'entry_time': datetime.now()}
def unpark_vehicle(self, license_plate):
# 除了现有逻辑,更新数据库中的出场时间和费用
vehicle_info = self.parked_vehicles.get(license_plate)
if vehicle_info:
exit_time = datetime.now()
hours_parked = (exit_time - vehicle_info['entry_time']).total_seconds() / 3600
vehicle_type = vehicle_info['vehicle'].get_vehicle_type()
fee = self.pricing_rules[vehicle_type].calculate_fee(hours_parked)
sql_update = "UPDATE parked_vehicles SET exit_time=%s, total_fee=%s WHERE license_plate=%s"
val = (exit_time, fee, license_plate)
self.cursor.execute(sql_update, val)
self.conn.commit()
del self.parked_vehicles[license_plate]
return fee
else:
raise ValueError("Vehicle not found in the system.")
class PricingRule:
def __init__(self, vehicle_type, hourly_rate, max_daily_rate=None):
self.vehicle_type = vehicle_type
self.hourly_rate = hourly_rate
self.max_daily_rate = max_daily_rate or float('inf')
def calculate_fee(self, hours_parked):
fee = hours_parked * self.hourly_rate
if self.max_daily_rate and fee > self.max_daily_rate:
return self.max_daily_rate
return fee
class Vehicle:
def __init__(self, license_plate, vehicle_type):
self.license_plate = license_plate
self.vehicle_type = vehicle_type
def get_license_plate(self):
return self.license_plate
def get_vehicle_type(self):
return self.vehicle_type
class ParkingLotManager:
def __init__(self):
self.pricing_rules = {}
self.parked_vehicles = {}
def add_pricing_rule(self, vehicle_type, hourly_rate, max_daily_rate=None):
self.pricing_rules[vehicle_type] = PricingRule(vehicle_type, hourly_rate, max_daily_rate)
def park_vehicle(self, vehicle):
self.parked_vehicles[vehicle.get_license_plate()] = {'vehicle': vehicle, 'entry_time': datetime.now()}
def unpark_vehicle(self, license_plate):
entry_time = self.parked_vehicles[license_plate]['entry_time']
parked_hours = (datetime.now() - entry_time).total_seconds() / 3600
vehicle_type = self.parked_vehicles[license_plate]['vehicle'].get_vehicle_type()
if vehicle_type in self.pricing_rules:
fee = self.pricing_rules[vehicle_type].calculate_fee(parked_hours)
del self.parked_vehicles[license_plate]
return fee
else:
raise ValueError("No pricing rule for this vehicle type.")
class ParkingSystemApp:
def __init__(self, master, parking_manager):
self.master = master
self.parking_manager = parking_manager
master.title("停车场管理系统")
self.vehicle_listbox = tk.Listbox(master, width=50)
self.vehicle_listbox.pack(pady=10)
self.search_entry = tk.Entry(master)
self.search_entry.pack(pady=5)
tk.Button(master, text="查询车辆", command=self.search_vehicle).pack(side=tk.LEFT, padx=5)
tk.Button(master, text="录入入场", command=self.add_vehicle).pack(side=tk.LEFT, padx=5)
tk.Button(master, text="删除出场", command=self.remove_vehicle).pack(side=tk.LEFT, padx=5)
tk.Button(master, text="退出系统", command=self.quit_app).pack(side=tk.RIGHT, padx=5)
# 示例数据,实际应用中应从数据库读取
self.vehicles = ["ABC123", "XYZ789", "CDE456"]
self.update_ui_vehicles()
def update_ui_vehicles(self):
self.vehicle_listbox.delete(0, tk.END)
for plate in self.parking_manager.parked_vehicles.keys():
self.vehicle_listbox.insert(tk.END, plate)
def search_vehicle(self):
query = self.search_entry.get().strip()
if query:
self.vehicle_listbox.delete(0, tk.END)
for plate in self.parking_manager.parked_vehicles.keys():
if query.lower() in plate.lower():
self.vehicle_listbox.insert(tk.END, plate)
def add_vehicle(self):
new_vehicle = simpledialog.askstring("录入车辆", "请输入车牌号:")
if new_vehicle and new_vehicle not in self.vehicles:
car = Vehicle(new_vehicle, "car")
parking_manager.park_vehicle(car) # 假设park_vehicle方法已更新数据库
self.update_ui_vehicles() # 添加车辆后立即刷新UI
def remove_vehicle(self):
selected = self.vehicle_listbox.curselection()
if selected:
plate = self.vehicle_listbox.get(selected[0])
fee = parking_manager.unpark_vehicle(plate)
messagebox.showinfo("停车费用", f"车辆 {plate} 的停车费用为:{fee}")
self.update_ui_vehicles() # 移除车辆后刷新UI
def quit_app(self):
self.master.destroy()
def login_success(username_entry, password_entry, parking_manager):
expected_username = "1"
expected_password = "1" # 这里设置具体的密码
entered_username = username_entry.get().strip()
entered_password = password_entry.get().strip()
if entered_username == expected_username and entered_password == expected_password:
login_window.withdraw()
open_main_system(parking_manager)
else:
messagebox.showerror("登录失败", "用户名或密码错误,请重试。")
def open_main_system(parking_manager):
main_system_window = tk.Toplevel(login_window)
main_system_window.title("停车场管理系统 - 主功能")
app = ParkingSystemApp(main_system_window, parking_manager)
main_system_window.protocol("WM_DELETE_WINDOW", lambda: [main_system_window.destroy(), login_window.destroy()])
# 初始化停车场管理器
parking_manager = ParkingLotManager()
parking_manager.add_pricing_rule("car", 2, 20) # 小型车每小时2元每日最高20元
# 登录界面
login_window = tk.Tk()
login_window.title("停车场管理系统 - 登录")
label_username = tk.Label(login_window, text="用户名:")
label_username.pack()
entry_username = tk.Entry(login_window)
entry_username.pack()
label_password = tk.Label(login_window, text="密码:")
label_password.pack()
entry_password = tk.Entry(login_window, show="*")
entry_password.pack()
button_login = tk.Button(login_window, text="登录", command=lambda: login_success(entry_username, entry_password, parking_manager))
button_login.pack(pady=10)
login_window.mainloop()

@ -1,32 +1,30 @@
import time
class User:
def __init__(self, username, password, role='user'):
"""
初始化用户对象
:param username: 用户名
:param password: 密码注意在实际应用中不应明文存储此处仅为示例
:param role: 用户角色'user'默认'admin'
"""
self.username = username
self.password = password # 实际应用中应加密存储
self.role = role
class User(object):
def __init__(self):
self.Username = []
self.Userpwd = []
self.Adminname = "xyh"
self.Adminpwd = "xyh"
def __str__(self):
"""返回用户的字符串表示"""
return f"用户名: {self.username}, 角色: {self.role}"
def login(self):
def change_password(self, new_password):
"""
用户登录
:return:{bool}True(登录成功进入管理员模式)/False(登录失败返回用户模式)
更改用户密码
:param new_password: 新密码
"""
cnt = 1 # counter for trial
while 1 <= cnt <= 5:
name = input('请输入用户名:')
pwd = input('请输入密码:')
if name == '' or pwd == '':
print('用户名或密码不能为空!')
continue
elif name == self.Adminname and pwd == self.Adminpwd:
return True
else:
if cnt <= 4:
print('用户名或密码错误,您还有%d次机会,请重试!' % (5-cnt))
cnt += 1
else:
print('机会已用尽,即将返回用户模式......')
time.sleep(2)
return False
self.password = new_password # 实际应用中应处理密码加密逻辑
def promote_to_admin(self):
"""提升用户为管理员角色"""
self.role = 'admin'
def demote_to_user(self):
"""降级用户为普通用户角色"""
self.role = 'user'

@ -1,202 +0,0 @@
import os
import logging
import re # 正则表达式
import time
# Sub module
from Car import Car, ParkManage, Model, Color
from User import User
from IO import *
# from GUI import * # TODO
def menu_select(isAdmin, park):
"""显示菜单返回str型操作码"""
if isAdmin == True:
# 管理员模式
while True:
os.system("cls")
print("""
***欢迎使用停车场管理系统***
## 管理员模式 ##
---北京第三区交通委提醒您---
| 道路千万条安全第一条 |
| 行车不规范亲人两行泪 |
---------------------------
本停车场总车位数%3d 当前空闲车位数%3d
1)停车
2)取车
3)显示车辆信息
4)查询车辆信息
5)编辑车辆信息
6)统计车辆信息
7)从文件加载车辆
8)切换至用户模式
9)关于
0)退出系统
""" % (park.max_car, park.max_car - len(park.carlist)))
c = input("请输入操作码(0~9):")
if re.match(r'(^\d$)', c):
if 0 <= int(c) <= 9: # c >= 0 and c <= 9
return c
else:
print("输入错误,请重试!")
else:
print("输入错误,请重试!")
'''
try:
c = int(input("请输入操作码(0~8):"))
except Exception as e:
logging.exception(e)
c = -1
continue
'''
elif isAdmin == False:
# 用户模式
while True:
os.system("cls")
print("""
***欢迎使用停车场管理系统***
## 用户模式 ##
---北京第三区交通委提醒您---
| 道路千万条安全第一条 |
| 行车不规范亲人两行泪 |
---------------------------
本停车场总车位数%3d 当前空闲车位数%3d
1)停车
2)取车
3)查询车辆信息
4)切换至管理员模式
5)关于
0)退出系统
""" % (park.max_car, park.max_car - len(park.carlist)))
c = input("请输入操作码(0~5):")
if re.match(r'(^\d$)', c):
if 0 <= int(c) <= 5: # c >= 0 and c <= 5
return c
else:
print("输入错误,请重试!")
else:
print("输入错误,请重试!")
'''
try:
c = int(input("请输入操作码(0~5):"))
except Exception as e:
print('请输入正确的操作码!')
logging.exception(e)
c = -1
continue
'''
def main():
park = ParkManage() # 建立并初始化车库
user = User() # 初始化用户
park = load_from_file(park, filename="cars.csv")[0] # 从文件初始化车辆信息
# user.login()
# isAdmin = True # TODO DEBUG 测试用
isAdmin = False # 程序启动时直接进入用户模式
while True:
choice = menu_select(isAdmin, park=park)
if not isAdmin:
# 用户
if choice == '0':
os.system("cls") # 清屏
write_to_file(park, filename="cars.csv") # 将车辆信息写入文件
print("Goodbye.\nHave a nice day!\n期待与您下一次的相遇! \n\n系统3秒后自动关闭...")
time.sleep(3)
exit(0)
elif choice == '1': # 停车
os.system("cls") # 清屏
park.park(isAdmin)
elif choice == '2': # 取车
os.system("cls")
park.pickup()
os.system("pause")
elif choice == '3': # 查车
os.system("cls")
park.inquire()
os.system("pause")
elif choice == '4': # 切换到管理员模式
# isAdmin = True # DEBUG
os.system("cls")
isAdmin = user.login() # 管理员登录
continue
elif choice == '5': # 关于
os.system("cls") # 清屏
print("""
停车场管理系统
Version:0.6.0
Copyright by Hzj.
All rights reserved.
""")
os.system("pause")
else:
pass
elif isAdmin:
# 管理员
if choice == '0': # 退出
os.system("cls") # 清屏
write_to_file(park, filename="cars.csv") # 将车辆信息写入文件
print("Goodbye.\nHave a nice day!\n期待与您下一次的相遇! \n\n系统3秒后自动关闭...")
time.sleep(3)
exit(0)
elif choice == '1': # 停车
os.system("cls") # 清屏
park.park(isAdmin)
elif choice == '2': # 取车
os.system("cls") # 清屏
park.pickup()
os.system("pause")
elif choice == '3': # 显示车辆信息
os.system("cls") # 清屏
park.display()
os.system("pause")
elif choice == '4': # 查询车辆信息
os.system("cls")
park.inquire()
os.system("pause")
elif choice == '5': # 编辑车辆信息
os.system("cls") # 清屏
park.edit()
os.system("pause")
elif choice == '6': # 统计车辆信息
os.system("cls") # 清屏
park.statistics()
os.system("pause")
elif choice == '7': # 从文件加载车辆
os.system("cls") # 清屏
park = load_new_file(park=park)
os.system("pause")
elif choice == '8': # 切换到用户模式
isAdmin = False
elif choice == '9': # 关于
os.system("cls") # 清屏
print("""
停车场管理系统
Version:0.6.0
Copyright by Hzj.
All rights reserved.
""")
os.system("pause")
else:
pass
if __name__ == '__main__':
main()

@ -0,0 +1,205 @@
import tkinter as tk
from tkinter import messagebox
from tkinter import simpledialog
from Car import Car
from ParkManage import ParkManage # 确保你的模块路径正确
from User import User
# 初始化停车场管理
park_manage_instance = ParkManage()
park = ParkManage()
# 创建一个用户实例
user1 = User('Alice', 'P@ssw0rd')
# 打印用户信息
print(user1)
# 修改用户密码
user1.change_password('NewP@ssw0rd')
# 提升用户为管理员
user1.promote_to_admin()
# 再次打印用户信息,查看角色是否变化
print(user1)
# 降级用户为普通用户
user1.demote_to_user()
# 最后一次打印用户信息
print(user1)
isAdmin = False
def on_park_click():
"""处理停车操作的回调函数"""
# 弹出对话框让用户输入车牌号
license_plate = simpledialog.askstring("停车", "请输入车牌号:")
if license_plate:
# 调用park对象的park方法传入用户输入的车牌号
success = park.park(license_plate)
if success:
messagebox.showinfo("停车成功", f"车牌号{license_plate}的车辆已成功停放。")
else:
messagebox.showerror("停车失败", "停车过程中出现问题,请重试。")
else:
messagebox.showwarning("警告", "车牌号不能为空,请重新输入。")
def on_pickup_click():
"""处理取车操作的回调函数"""
# 弹出对话框让用户输入车牌号
license_plate = simpledialog.askstring("取车", "请输入车牌号:")
if license_plate:
# 调用park对象的pickup方法传入用户输入的车牌号尝试取车
success = park.pickup(license_plate)
if success:
messagebox.showinfo("取车成功", f"车牌号为{license_plate}的车辆已成功取走。")
else:
messagebox.showerror("取车失败", f"车牌号为{license_plate}的车辆取车失败。请检查车牌号是否正确或车辆是否已取走。")
else:
messagebox.showwarning("警告", "车牌号不能为空,请重新输入。")
def on_inquire_click():
"""处理查询车辆信息操作的回调函数"""
# 弹出对话框让用户输入车牌号
license_plate = simpledialog.askstring("查询车辆信息", "请输入车牌号:")
if license_plate:
try:
# 调用park对象的query_car_info方法传入用户输入的车牌号查询车辆信息
car_info = park.query_car_info(license_plate)
if car_info:
# 假设query_car_info返回车辆信息的字典展示相关信息
message = (
f"车牌号: {car_info['license_plate']}\n"
f"车型: {car_info['model']}\n"
f"颜色: {car_info['color']}\n"
f"停放时间: {car_info['parked_time'].strftime('%Y-%m-%d %H:%M:%S')}\n"
f"取车时间: {car_info['picked_up_time'].strftime('%Y-%m-%d %H:%M:%S') if car_info['picked_up_time'] else '未取车'}"
)
messagebox.showinfo("车辆信息", message)
else:
messagebox.showerror("查询结果", "未找到该车牌号的车辆信息。")
except Exception as e:
messagebox.showerror("查询错误", f"查询过程中发生错误: {e}")
else:
messagebox.showwarning("警告", "车牌号不能为空,请重新输入。")
def on_display_info_click():
try:
# 调用ParkManage类中的方法来获取所有车辆信息
car_info = park.display_all_cars_info()
if cars_info:
# 假设cars_info是一个包含车辆信息的列表每个元素是车辆的字典表示
info_text = "\n".join(
[f"车牌号: {car['license_plate']}, 停放时间: {car['parked_time'].strftime('%Y-%m-%d %H:%M:%S')}"
f"{', 取车时间: ' + car['picked_up_time'].strftime('%Y-%m-%d %H:%M:%S') if car['picked_up_time'] else ''}"
for car in cars_info])
messagebox.showinfo("车辆信息", info_text)
else:
messagebox.showinfo("信息提示", "当前没有车辆信息可显示。")
except Exception as e:
messagebox.showerror("错误", f"显示车辆信息时发生错误: {e}")
def on_edit_info_click():
# 从界面获取车牌号、车型和颜色
license_plate = license_plate_entry.get().strip()
new_model = model_entry.get().strip()
new_color = color_entry.get().strip()
if not license_plate:
messagebox.showerror("错误", "请输入车牌号进行编辑!")
return
try:
# 假设ParkManage类有一个edit_car_info方法用于更新车辆信息
success = park_manage_instance.edit_car_info(license_plate, new_model=new_model, new_color=new_color)
if success:
messagebox.showinfo("成功", "车辆信息已成功更新。")
else:
messagebox.showinfo("失败", "未能找到或更新车辆信息,请检查车牌号是否正确。")
except Exception as e:
messagebox.showerror("错误", f"编辑车辆信息时发生错误: {e}")
def on_statistics_click():
try:
# 假设ParkManage类中包含以下统计方法
parked_cars_count = park_manage_instance.count_parked_cars()
empty_slots = park_manage_instance.count_empty_slots(total_slots=100) # 假设总车位数为100根据实际情况调整
most_frequent_time = park_manage_instance.most_frequent_parking_time()
# 构建统计信息字符串
stats_message = (
f"当前停车数量: {parked_cars_count}\n"
f"空闲车位数: {empty_slots}\n"
f"最频繁的停车时段: {most_frequent_time}\n"
)
messagebox.showinfo("统计信息", stats_message)
except Exception as e:
messagebox.showerror("错误", f"统计车辆信息时发生错误: {e}")
def on_switch_mode():
"""处理模式切换的回调函数"""
global isAdmin
isAdmin = not isAdmin
refresh_ui()
def on_exit_click():
"""处理退出操作的回调函数"""
if messagebox.askyesno("退出", "确定要退出吗?"):
window.destroy() # 关闭窗口
def refresh_ui():
"""根据当前模式刷新界面"""
for widget in window.winfo_children():
widget.destroy()
tk.Label(window, text=f"欢迎使用停车场管理系统 - {'管理员' if isAdmin else '用户'}模式").pack()
buttons = [
("停车", on_park_click),
("取车", on_pickup_click),
("查询车辆信息", on_inquire_click),
]
if isAdmin:
additional_buttons = [
("显示车辆信息", on_display_info_click),
("编辑车辆信息", on_edit_info_click),
("统计信息", on_statistics_click),
("切换至用户模式", on_switch_mode),
]
buttons.extend(additional_buttons)
else:
buttons.append(("切换至管理员模式", on_switch_mode))
buttons.append(("退出", on_exit_click))
for idx, (text, cmd) in enumerate(buttons):
tk.Button(window, text=text, command=cmd).pack(fill=tk.X, pady=5)
def main_gui():
global window
window = tk.Tk()
window.title("停车场管理系统")
refresh_ui() # 初始化界面
window.mainloop()
if __name__ == "__main__":
main_gui()
Loading…
Cancel
Save