import logging from PySide6.QtWidgets import QMessageBox from PySide6.QtCore import Qt, Signal from ui.loading_dialog_ui import LoadingDialogUI from widgets.order_query_dialog import OrderQueryDialog from utils.app_mode import AppMode from utils.pallet_type_manager import PalletTypeManager from apis.gc_api import GcApi class LoadingDialog(LoadingDialogUI): """上料操作对话框""" # 定义信号,用于向主窗口传递托盘号 tray_code_signal = Signal(str, str, str, str) # 定义信号,用于向主窗口传递订单号 order_code_signal = Signal(str) def __init__(self, parent=None, user_id=None, user_name=None, corp_id=None): super().__init__() self.parent = parent self.user_id = user_id, self.user_name = user_name self.corp_id = corp_id # 存储订单数据 # self.order_data = None # 彻底禁用对话框的回车键关闭功能 self.setModal(True) # 禁用所有按钮的默认行为 self.confirm_button.setAutoDefault(False) self.confirm_button.setDefault(False) self.cancel_button.setAutoDefault(False) self.cancel_button.setDefault(False) # 设置对话框特性,按下Escape键才能关闭 self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) # 确保焦点跟踪器能够跟踪此对话框中的输入框 from utils.focus_tracker import FocusTracker self.focus_tracker = FocusTracker.get_instance() # 连接信号和槽 self.connect_signals() def connect_signals(self): """连接信号和槽""" # 订单查询按钮点击事件 self.order_query_btn.clicked.connect(self.show_order_query_dialog) # 订单号输入框回车事件触发查询 self.order_input.returnPressed.connect(self.handle_order_return_pressed) # 确认按钮点击事件 self.confirm_button.clicked.connect(self.accept) # 取消按钮点击事件 self.cancel_button.clicked.connect(self.reject) # 托盘号输入框回车事件 self.tray_input.returnPressed.connect(self.on_tray_entered) def handle_order_return_pressed(self): """处理订单输入框的回车事件""" logging.info("订单输入框回车事件触发") # 获取当前订单号值 order_code = self.order_input.text().strip() if not order_code: QMessageBox.warning(self, "提示", "请输入订单号") return # 发送订单号到主窗口 from widgets.main_window import MainWindow main_window = self.parent if main_window and isinstance(main_window, MainWindow): logging.info(f"发送订单号到主窗口: {order_code}") self.order_code_signal.emit(order_code) # 查询订单信息 self.on_order_query(order_code) # 阻止事件继续传播 return True def show_order_query_dialog(self): """显示订单查询对话框""" try: # 创建订单查询对话框 dialog = OrderQueryDialog(self) # 连接订单选择信号 dialog.order_selected.connect(self.on_order_selected) # 显示对话框 dialog.exec() except Exception as e: logging.error(f"显示订单查询对话框失败: {e}") QMessageBox.critical(self, "错误", f"显示订单查询对话框失败: {str(e)}") def on_order_selected(self, order_data): """处理订单选择事件 Args: order_data: 订单数据字典 """ try: # 存储订单数据 self.order_data = order_data # 更新UI # 注意:此时order_data["note"]已经被修改为order_data["mo"]的值 self.order_input.setText(order_data.get("mo", "")) # 更新轴型 self.axis_value.setText(order_data.get("zx_name", "--")) # 更新数量 self.quantity_value.setText(str(order_data.get("sl", "--"))) # 更新重量 self.weight_value.setText(str(order_data.get("zx_zl", "--"))) # 自动填充托盘号 if "xpack" in order_data: self.tray_input.setText(order_data["xpack"]) # 发送订单号到主窗口 from widgets.main_window import MainWindow main_window = self.parent if main_window and isinstance(main_window, MainWindow): # 使用note字段作为订单号(已经被修改为mo的值) order_code = order_data.get("note", "") logging.info(f"发送订单号到主窗口: {order_code}") self.order_code_signal.emit(order_code) # 设置焦点到托盘号输入框 self.tray_input.setFocus() except Exception as e: logging.error(f"处理订单选择事件失败: {e}") QMessageBox.critical(self, "错误", f"处理订单选择事件失败: {str(e)}") def on_order_query(self, order_code): """查询订单信息,同时生成托盘号,并且回显到页面上""" try: # 构建查询参数 query_params = { "srch_mo": order_code, "srch_note": order_code, "corp_id": self.corp_id } # 创建订单查询对话框(仅用于执行查询) dialog = OrderQueryDialog(self) # 执行查询 results = dialog.query_orders(query_params) # 处理查询结果 if results: # 如果只有一个结果,直接使用 if len(results) == 1: self.on_order_selected(results[0]) return else: # 如果有多个结果,显示查询对话框让用户选择 dialog.update_result_table(results) dialog.order_selected.connect(self.on_order_selected) dialog.exec() return # 如果没有结果,并且不是API模式,显示提示 if not AppMode.is_api(): QMessageBox.warning(self, "提示", f"未找到订单: {order_code}") return # 如果是API模式,尝试使用旧的API方式查询 # 调用接口 gc_api = GcApi() # 防止response为None导致异常 # 获取工程号信息,并且初始化数据 order_response = gc_api.get_order_info(order_code, self.corp_id) # 生成托盘号 if order_response and order_response.get("status", False): # 将接口数据保存到数据库,用于后续的关联使用 from dao.inspection_dao import InspectionDAO inspection_dao = InspectionDAO() order_info = order_response.get("data", {})[0] # 设置轴数 order_info['user_id'] = self.user_id[0] order_info['user_name'] = self.user_name order_info['data_corp'] = self.corp_id inspection_dao.save_order_info(order_code, order_info) self.axis_value.setText(order_info['zx_name']) self.quantity_value.setText(str(order_info['sl'])) self.weight_value.setText(str(order_info['zx_zl'])) # 存储订单数据 self.order_data = order_info else: QMessageBox.warning(self, "提示", f"未找到订单: {order_code}") return xpack_response = gc_api.get_xpack(order_code, self.corp_id) if xpack_response and xpack_response.get("status", False): xpack = xpack_response['xpack'] self.tray_input.setText(xpack) self.pallet_tier_value.setText('3') # 发送托盘号到主窗口 from widgets.main_window import MainWindow main_window = self.parent if main_window and isinstance(main_window, MainWindow): # 检查托盘号是否已存在 existed = False for i in range(main_window.tray_edit.count()): if main_window.tray_edit.itemText(i) == xpack: existed = True break # 如果不存在,则添加 if not existed: logging.info(f"添加托盘号到主窗口: {xpack}") main_window.tray_edit.addItem(xpack) # 设置当前选中的托盘号 main_window.tray_edit.setCurrentText(xpack) logging.info(f"设置主窗口当前托盘号: {xpack}") return order_info except Exception as e: logging.error(f"查询订单信息失败: {e}") QMessageBox.critical(self, "错误", f"查询订单信息失败: {str(e)}") def on_xpack_query(self, tray_id): """通过托盘号查询订单信息,并回显到页面(完全仿照on_order_query)""" try: query_params = { "xpack": tray_id, "corp_id": self.corp_id } dialog = OrderQueryDialog(self) results = dialog.query_orders_xpack(query_params) if results: if len(results) == 1: self.on_order_selected(results[0]) return else: dialog.update_result_table(results) dialog.order_selected.connect(self.on_order_selected) dialog.exec() return QMessageBox.warning(self, "提示", "未找到该托盘号对应的订单信息") except Exception as e: logging.error(f"托盘号查订单接口异常: {e}") QMessageBox.warning(self, "错误", f"托盘号查订单接口异常: {str(e)}") def on_tray_entered(self): tray_id = self.tray_input.text().strip() if not tray_id: QMessageBox.warning(self, "提示", "请输入托盘号") return self.on_xpack_query(tray_id) self.pallet_tier_value.setFocus() def keyPressEvent(self, event): """重写键盘事件处理,防止回车关闭对话框""" # 如果按下回车键 if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter: logging.info(f"捕获到回车键事件,当前焦点部件: {self.focusWidget()}") # 如果焦点在托盘输入框上,触发查询 if self.focusWidget() == self.tray_input: event.accept() # 消费掉这个事件 return # 如果焦点在确认按钮上,则允许默认行为(确认) if self.focusWidget() == self.confirm_button: return super().keyPressEvent(event) # 其他情况下,阻止回车事件传播 event.accept() # 消费掉这个事件 return # 其他键位事件交给父类处理 super().keyPressEvent(event) def accept(self): """重写接受方法,确保在确认前所有数据都已处理""" logging.info("确认按钮被点击或回车触发确认") # 检查托盘层数是否有值 tier_value = self.pallet_tier_value.text().strip() if not tier_value: QMessageBox.warning(self, "提示", "请输入托盘层数") return # 获取包装号 pallet_code = self.tray_input.text().strip() if not pallet_code: QMessageBox.warning(self, "提示", "请输入托盘号") return # 检查订单号 order_id = self.order_input.text().strip() if not order_id: QMessageBox.warning(self, "提示", "请输入订单号") self.order_input.setFocus() return # if not self.order_data: # QMessageBox.warning(self, "提示", "请先查询订单信息") # return try: # 保存托盘档案信息 pallet_manager = PalletTypeManager.get_instance() success = pallet_manager.save_pallet_archives( pallet_code=pallet_code, tier=int(tier_value), user_id=self.user_id[0], user_name=self.user_name ) if not success: QMessageBox.warning(self, "提示", "保存托盘档案失败") return logging.info(f"已保存托盘档案:托盘号={pallet_code}, 层数={tier_value}") except Exception as e: logging.error(f"保存托盘档案时发生错误: {str(e)}") QMessageBox.warning(self, "错误", f"保存托盘档案失败: {str(e)}") return # 确保主窗口启动了监听 from widgets.main_window import MainWindow main_window = self.parent if main_window and isinstance(main_window, MainWindow): # 确保主窗口已启动监听 try: if not hasattr(main_window, 'modbus_monitor') or not main_window.modbus_monitor.is_running(): main_window.setup_modbus_monitor() logging.info("已在LoadingDialog确认时启动Modbus监控") # 启动串口监听 main_window.serial_manager.auto_open_configured_ports() # 启动键盘监听器 main_window.serial_manager.start_keyboard_listener() logging.info("已在LoadingDialog确认时启动键盘监听器") except Exception as e: logging.error(f"LoadingDialog确认时启动监听失败: {str(e)}") # 调用父类的accept方法关闭对话框 super().accept() def reject(self): """重写拒绝方法""" logging.info("取消按钮被点击或ESC触发取消") # 调用父类的reject方法关闭对话框 super().reject() def get_loading_data(self): """获取上料数据 Returns: dict: 上料数据字典 """ return { "order_id": self.order_input.text().strip(), "tray_id": self.tray_input.text().strip(), "pallet_tier": self.pallet_tier_value.text().strip(), "order_data": self.order_data }