diff --git a/main.py b/main.py index 0ab2bfe..d1d3c76 100644 --- a/main.py +++ b/main.py @@ -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"{type_text} - {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: diff --git a/parking_config.json b/parking_config.json new file mode 100644 index 0000000..298161f --- /dev/null +++ b/parking_config.json @@ -0,0 +1,5 @@ +{ + "free_parking_duration": 5, + "billing_cycle": 3, + "price_per_cycle": 5.0 +} \ No newline at end of file