出入库记录上线

This commit is contained in:
2025-10-19 22:42:30 +08:00
parent 418f7f3bc9
commit 15a83a5f06
2 changed files with 124 additions and 1 deletions

120
main.py
View File

@@ -588,6 +588,9 @@ class MainWindow(QMainWindow):
# 白名单存储
self.whitelist = set() # 存储白名单车牌号
# 出入库记录存储
self.parking_records = [] # 存储所有出入库记录
# 帧率检测相关
self.frame_times = deque(maxlen=30) # 存储最近30帧的时间戳
self.current_fps = 30.0 # 默认帧率
@@ -918,11 +921,53 @@ class MainWindow(QMainWindow):
control_layout.addWidget(whitelist_group)
control_layout.addWidget(manual_group)
# 出入库记录显示区域
records_frame = QFrame()
records_frame.setFrameStyle(QFrame.StyledPanel)
records_frame.setStyleSheet("""
QFrame {
background-color: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 10px;
}
""")
records_layout = QVBoxLayout(records_frame)
records_layout.setSpacing(8)
# 记录标题
records_title = QLabel("出入库记录")
records_title.setFont(QFont("Microsoft YaHei", 11, QFont.Bold))
records_title.setStyleSheet("QLabel { color: #495057; margin-bottom: 5px; }")
# 记录滚动区域
records_scroll = QScrollArea()
records_scroll.setWidgetResizable(True)
records_scroll.setMaximumHeight(200)
records_scroll.setStyleSheet("""
QScrollArea {
border: 1px solid #e9ecef;
background-color: white;
border-radius: 4px;
}
""")
self.records_widget = QWidget()
self.records_layout = QVBoxLayout(self.records_widget)
self.records_layout.setAlignment(Qt.AlignTop)
self.records_layout.setSpacing(2)
records_scroll.setWidget(self.records_widget)
records_layout.addWidget(records_title)
records_layout.addWidget(records_scroll)
right_layout.addWidget(title_label)
right_layout.addLayout(method_layout)
right_layout.addWidget(self.count_label)
right_layout.addWidget(scroll_area)
right_layout.addWidget(control_frame)
right_layout.addWidget(records_frame)
right_layout.addWidget(self.current_method_label)
# 添加到主布局
@@ -1528,7 +1573,7 @@ class MainWindow(QMainWindow):
# 显示费用确认对话框
if self.show_parking_fee_dialog(plate_number, time_diff):
# 用户确认缴费,发送时间间隔命令
message = f"{plate_number} {int(time_diff)}sec"
message = f"{plate_number} {int(time_diff)}seconds"
try:
send_command(1, message)
print(f"发送道闸命令: {message}")
@@ -1539,6 +1584,10 @@ class MainWindow(QMainWindow):
'command_sent': True
}
# 计算并记录出库信息(包含缴费金额)
fee_amount = self.calculate_parking_fee(time_diff)
self.add_parking_record(plate_number, 'exit', fee_amount)
# 清除记录,使第三次识别时重新按首次处理
del self.plate_records[plate_number]
@@ -1566,6 +1615,9 @@ class MainWindow(QMainWindow):
'command_sent': True
}
# 记录入库信息
self.add_parking_record(plate_number, 'entry')
# 记录车牌信息,等待二次识别
self.plate_records[plate_number] = {
'first_time': current_time,
@@ -1665,6 +1717,72 @@ class MainWindow(QMainWindow):
else:
return False # 未缴费或取消,拒绝开闸
def add_parking_record(self, plate_number, record_type, fee_amount=0):
"""添加出入库记录"""
record = {
'plate_number': plate_number,
'type': record_type, # 'entry' 或 'exit'
'timestamp': datetime.now(),
'fee_amount': fee_amount
}
self.parking_records.append(record)
self.update_parking_records_display()
def update_parking_records_display(self):
"""更新出入库记录显示"""
# 清空现有记录显示
for i in reversed(range(self.records_layout.count())):
child = self.records_layout.itemAt(i).widget()
if child:
child.setParent(None)
# 显示最近的20条记录
recent_records = self.parking_records[-20:] if len(self.parking_records) > 20 else self.parking_records
for record in reversed(recent_records): # 最新记录在上方
record_widget = self.create_record_widget(record)
self.records_layout.addWidget(record_widget)
def create_record_widget(self, record):
"""创建单条记录的显示widget"""
widget = QFrame()
widget.setFrameStyle(QFrame.Box)
widget.setStyleSheet("""
QFrame {
background-color: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 5px;
margin: 2px;
padding: 5px;
}
""")
layout = QVBoxLayout(widget)
layout.setContentsMargins(8, 5, 8, 5)
layout.setSpacing(3)
# 车牌号和类型
type_text = "入库" if record['type'] == 'entry' else "出库"
type_color = "#28a745" if record['type'] == 'entry' else "#dc3545"
header_label = QLabel(f"<b style='color: {type_color}'>{type_text}</b> - {record['plate_number']}")
header_label.setStyleSheet("font-size: 12px; font-weight: bold;")
layout.addWidget(header_label)
# 时间
time_str = record['timestamp'].strftime("%Y-%m-%d %H:%M:%S")
time_label = QLabel(f"时间: {time_str}")
time_label.setStyleSheet("font-size: 10px; color: #6c757d;")
layout.addWidget(time_label)
# 费用(仅出库记录显示)
if record['type'] == 'exit' and record['fee_amount'] > 0:
fee_label = QLabel(f"缴费金额: ¥{record['fee_amount']:.2f}")
fee_label.setStyleSheet("font-size: 10px; color: #fd7e14; font-weight: bold;")
layout.addWidget(fee_label)
return widget
def closeEvent(self, event):
"""窗口关闭事件"""
if self.camera_thread and self.camera_thread.running:

5
parking_config.json Normal file
View File

@@ -0,0 +1,5 @@
{
"free_parking_duration": 5,
"billing_cycle": 3,
"price_per_cycle": 5.0
}