2025-06-17 09:31:03 +08:00
|
|
|
|
from ui.unloading_dialog_ui import UnloadingDialogUI
|
|
|
|
|
|
from apis.tary_api import TaryApi
|
|
|
|
|
|
from PySide6.QtCore import Qt, Signal
|
|
|
|
|
|
from PySide6.QtWidgets import QMessageBox, QDialog
|
|
|
|
|
|
import logging
|
2025-06-17 14:12:34 +08:00
|
|
|
|
from utils.app_mode import AppMode
|
|
|
|
|
|
from utils.pallet_type_manager import PalletTypeManager
|
2025-06-24 16:33:33 +08:00
|
|
|
|
from utils.modbus_utils import ModbusUtils
|
2025-06-17 09:31:03 +08:00
|
|
|
|
|
|
|
|
|
|
class UnloadingDialog(UnloadingDialogUI):
|
|
|
|
|
|
# 定义一个信号,用于向主窗口传递托盘号
|
|
|
|
|
|
tray_code_signal = Signal(str, str, str, str)
|
|
|
|
|
|
|
2025-06-20 17:47:03 +08:00
|
|
|
|
def __init__(self, parent=None, user_id=None):
|
2025-06-17 09:31:03 +08:00
|
|
|
|
"""初始化下料对话框"""
|
|
|
|
|
|
super().__init__()
|
|
|
|
|
|
self.parent = parent
|
2025-06-20 17:47:03 +08:00
|
|
|
|
self.user_id = user_id
|
|
|
|
|
|
self.current_tier = None # 添加一个变量来保存当前层数
|
2025-06-17 09:31:03 +08:00
|
|
|
|
# 初始化API
|
|
|
|
|
|
self.tary_api = TaryApi()
|
|
|
|
|
|
|
|
|
|
|
|
# 彻底禁用对话框的回车键关闭功能
|
|
|
|
|
|
self.setModal(True)
|
|
|
|
|
|
# 禁用所有按钮的默认行为
|
|
|
|
|
|
self.confirm_button.setAutoDefault(False)
|
|
|
|
|
|
self.confirm_button.setDefault(False)
|
|
|
|
|
|
self.cancel_button.setAutoDefault(False)
|
|
|
|
|
|
self.cancel_button.setDefault(False)
|
2025-06-20 17:47:03 +08:00
|
|
|
|
|
2025-06-17 09:31:03 +08:00
|
|
|
|
# 设置对话框特性,按下Escape键才能关闭
|
|
|
|
|
|
self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
|
|
|
|
|
|
|
2025-06-20 17:47:03 +08:00
|
|
|
|
# 初始化托盘类型下拉列表
|
|
|
|
|
|
self.init_pallet_types()
|
|
|
|
|
|
|
2025-06-17 09:31:03 +08:00
|
|
|
|
# 绑定事件
|
|
|
|
|
|
self.setup_connections()
|
|
|
|
|
|
|
2025-06-20 17:47:03 +08:00
|
|
|
|
def init_pallet_types(self):
|
|
|
|
|
|
"""初始化托盘类型下拉列表"""
|
|
|
|
|
|
# 从数据库获取托盘类型列表
|
|
|
|
|
|
pallet_type_manager = PalletTypeManager.get_instance()
|
|
|
|
|
|
pallet_types = pallet_type_manager.get_pallet_types()
|
|
|
|
|
|
# 清空现有选项
|
|
|
|
|
|
self.pallet_type_input.clear()
|
|
|
|
|
|
# 添加新选项
|
|
|
|
|
|
for pallet_id, pallet_name in pallet_types.items():
|
|
|
|
|
|
self.pallet_type_input.addItem(pallet_name, userData=pallet_id)
|
|
|
|
|
|
logging.info(f"从数据库加载{len(pallet_types)}个托盘类型")
|
|
|
|
|
|
|
|
|
|
|
|
def get_current_pallet_type_id(self):
|
|
|
|
|
|
"""获取当前选中的托盘类型ID"""
|
|
|
|
|
|
current_index = self.pallet_type_input.currentIndex()
|
|
|
|
|
|
if current_index >= 0:
|
|
|
|
|
|
pallet_id = self.pallet_type_input.itemData(current_index)
|
|
|
|
|
|
logging.info(f"获取当前选中的托盘类型ID: {pallet_id}")
|
|
|
|
|
|
return pallet_id
|
|
|
|
|
|
logging.warning("未获取到托盘类型ID")
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
def get_current_tier(self):
|
|
|
|
|
|
"""获取当前托盘的层数"""
|
2025-06-21 15:04:16 +08:00
|
|
|
|
tier = self.tier_input.text().strip()
|
|
|
|
|
|
if not tier:
|
|
|
|
|
|
return self.current_tier if self.current_tier else "3"
|
|
|
|
|
|
return tier
|
2025-06-20 17:47:03 +08:00
|
|
|
|
|
2025-06-17 09:31:03 +08:00
|
|
|
|
def setup_connections(self):
|
|
|
|
|
|
"""设置事件连接"""
|
|
|
|
|
|
# 托盘号输入框回车事件触发查询
|
|
|
|
|
|
self.tray_input.returnPressed.connect(self.handle_tray_return_pressed)
|
2025-06-17 14:12:34 +08:00
|
|
|
|
# 移除editingFinished事件,避免重复触发查询
|
|
|
|
|
|
# self.tray_input.editingFinished.connect(self.on_tray_query)
|
2025-06-17 09:31:03 +08:00
|
|
|
|
|
|
|
|
|
|
# 确认按钮点击事件
|
|
|
|
|
|
self.confirm_button.clicked.connect(self.accept)
|
|
|
|
|
|
|
|
|
|
|
|
# 取消按钮点击事件
|
|
|
|
|
|
self.cancel_button.clicked.connect(self.reject)
|
|
|
|
|
|
|
|
|
|
|
|
def handle_tray_return_pressed(self):
|
|
|
|
|
|
"""处理托盘输入框的回车事件"""
|
|
|
|
|
|
# 阻止事件传播
|
|
|
|
|
|
logging.info("托盘输入框回车事件触发")
|
|
|
|
|
|
self.on_tray_query()
|
|
|
|
|
|
|
|
|
|
|
|
# 阻止事件继续传播
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
def on_tray_query(self):
|
|
|
|
|
|
"""查询托盘信息"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
tray_code = self.tray_input.text().strip()
|
2025-06-21 15:04:16 +08:00
|
|
|
|
tier = self.tier_input.text().strip() # 获取用户输入的层数
|
2025-06-20 17:47:03 +08:00
|
|
|
|
pallet_type = self.pallet_type_input.currentText().strip()
|
2025-06-17 09:31:03 +08:00
|
|
|
|
if not tray_code:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"查询托盘号: {tray_code}")
|
2025-06-21 15:04:16 +08:00
|
|
|
|
# 初始化托盘类型管理器
|
|
|
|
|
|
pallet_type_manager = PalletTypeManager.get_instance()
|
2025-06-20 17:47:03 +08:00
|
|
|
|
|
2025-06-17 14:12:34 +08:00
|
|
|
|
if AppMode.is_api():
|
|
|
|
|
|
self.tary_api = TaryApi()
|
2025-06-21 15:04:16 +08:00
|
|
|
|
# 调用API获取托盘信息
|
2025-06-17 14:12:34 +08:00
|
|
|
|
response = self.tary_api.get_tary_info(tray_code)
|
2025-06-20 17:47:03 +08:00
|
|
|
|
if response.get("success", False) and response.get("data"):
|
|
|
|
|
|
tray_data = response.get("data", {})
|
2025-06-21 15:04:16 +08:00
|
|
|
|
logging.info(f"API返回托盘数据: {tray_data}")
|
|
|
|
|
|
# 如果用户输入了层数,使用用户输入的层数
|
|
|
|
|
|
if tier:
|
|
|
|
|
|
tray_data["tier"] = tier
|
|
|
|
|
|
pallet_type_manager.save_pallet_info(tray_code, tray_data, self.user_id)
|
|
|
|
|
|
else:
|
|
|
|
|
|
# API查询失败,保存基本信息到数据库
|
|
|
|
|
|
logging.info(f"API查询失败,保存基本信息到数据库")
|
2025-06-24 16:33:33 +08:00
|
|
|
|
# if not pallet_type or not tier:
|
|
|
|
|
|
# QMessageBox.warning(self, "提示", "请选择托盘类型和层数")
|
|
|
|
|
|
# return
|
2025-06-21 15:04:16 +08:00
|
|
|
|
pallet_info = {
|
|
|
|
|
|
"cc": pallet_type,
|
|
|
|
|
|
"cs": tier # 使用用户输入的层数
|
|
|
|
|
|
}
|
|
|
|
|
|
pallet_type_manager.save_pallet_info(tray_code, pallet_info, self.user_id)
|
2025-06-17 14:12:34 +08:00
|
|
|
|
else:
|
2025-06-21 15:04:16 +08:00
|
|
|
|
# 查询数据库中的托盘信息
|
2025-06-17 14:12:34 +08:00
|
|
|
|
pallet_info = pallet_type_manager.get_pallet_info_by_pallet_id(tray_code)
|
2025-06-20 17:47:03 +08:00
|
|
|
|
if not pallet_info:
|
2025-06-21 15:04:16 +08:00
|
|
|
|
# 数据库中没有记录,保存基本信息
|
|
|
|
|
|
logging.info(f"数据库中未找到记录,保存基本信息")
|
2025-06-24 16:33:33 +08:00
|
|
|
|
# if not pallet_type or not tier:
|
|
|
|
|
|
# QMessageBox.warning(self, "提示", "请选择托盘类型和层数")
|
|
|
|
|
|
# return
|
2025-06-20 17:47:03 +08:00
|
|
|
|
pallet_info = {
|
|
|
|
|
|
"cc": pallet_type,
|
2025-06-21 15:04:16 +08:00
|
|
|
|
"cs": tier # 使用用户输入的层数
|
2025-06-17 14:12:34 +08:00
|
|
|
|
}
|
2025-06-21 15:04:16 +08:00
|
|
|
|
pallet_type_manager.save_pallet_info(tray_code, pallet_info, self.user_id)
|
2025-06-20 17:47:03 +08:00
|
|
|
|
|
2025-06-21 15:04:16 +08:00
|
|
|
|
# 重新获取完整的托盘信息
|
2025-06-20 17:47:03 +08:00
|
|
|
|
pallet_info = pallet_type_manager.get_pallet_detail(tray_code)
|
2025-06-21 15:04:16 +08:00
|
|
|
|
if not pallet_info:
|
|
|
|
|
|
logging.warning(f"无法获取托盘详细信息: {tray_code}")
|
|
|
|
|
|
pallet_info = {
|
|
|
|
|
|
"zx_name": "--",
|
|
|
|
|
|
"cz": "--",
|
|
|
|
|
|
"weight": "0",
|
|
|
|
|
|
"amount": "0",
|
|
|
|
|
|
"tier": tier if tier else "4", # 使用用户输入的层数,如果没有则默认3层
|
|
|
|
|
|
"pallet_name": pallet_type
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# 显示托盘相关信息
|
|
|
|
|
|
axis_type = str(pallet_info.get("zx_name", "--"))
|
|
|
|
|
|
material = str(pallet_info.get("cz", "--"))
|
|
|
|
|
|
weight = str(pallet_info.get("weight", "--"))
|
|
|
|
|
|
amount = str(pallet_info.get("amount", "--"))
|
|
|
|
|
|
self.current_tier = pallet_info.get("cs", tier if tier else "4") # 优先使用数据库中的层数,其次是用户输入的层数,最后是默认值
|
|
|
|
|
|
|
|
|
|
|
|
logging.info(f"显示托盘信息: 轴型={axis_type}, 材质={material}, 重量={weight}, 层数={self.current_tier}")
|
2025-06-20 17:47:03 +08:00
|
|
|
|
|
2025-06-21 15:04:16 +08:00
|
|
|
|
# 设置显示值
|
|
|
|
|
|
self.axis_value.setText(axis_type)
|
|
|
|
|
|
self.material_tier_value.setPlaceholderText(material)
|
|
|
|
|
|
self.material_tier_value.setText("") # 清空文本,让用户输入
|
|
|
|
|
|
self.quantity_value.setText(amount)
|
|
|
|
|
|
self.weight_value.setText(f"{weight} kg")
|
|
|
|
|
|
self.tier_input.setText(str(self.current_tier)) # 设置层数输入框的值
|
|
|
|
|
|
self.pallet_type_input.setCurrentText(pallet_info.get("pallet_name", "--"))
|
2025-06-20 17:47:03 +08:00
|
|
|
|
|
2025-06-21 15:04:16 +08:00
|
|
|
|
# 发送托盘号到主窗口
|
|
|
|
|
|
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) == tray_code:
|
|
|
|
|
|
existed = True
|
|
|
|
|
|
break
|
2025-06-17 09:31:03 +08:00
|
|
|
|
|
2025-06-21 15:04:16 +08:00
|
|
|
|
# 如果不存在,则添加
|
|
|
|
|
|
if not existed:
|
|
|
|
|
|
logging.info(f"添加托盘号到主窗口: {tray_code}")
|
|
|
|
|
|
main_window.tray_edit.addItem(tray_code)
|
2025-06-17 09:31:03 +08:00
|
|
|
|
|
2025-06-21 15:04:16 +08:00
|
|
|
|
# 设置当前选中的托盘号
|
|
|
|
|
|
main_window.tray_edit.setCurrentText(tray_code)
|
|
|
|
|
|
logging.info(f"设置主窗口当前托盘号: {tray_code}")
|
|
|
|
|
|
|
2025-06-17 09:31:03 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logging.error(f"查询托盘信息异常: {str(e)}")
|
2025-06-21 15:04:16 +08:00
|
|
|
|
QMessageBox.critical(self, "查询异常", f"查询托盘信息时发生异常: {str(e)}")
|
2025-06-17 14:12:34 +08:00
|
|
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
|
# 不需要重复调用on_tray_query,因为returnPressed信号已经处理了
|
|
|
|
|
|
event.accept() # 消费掉这个事件
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
# 如果焦点在确认按钮上,则允许默认行为(确认)
|
|
|
|
|
|
if self.focusWidget() == self.confirm_button:
|
|
|
|
|
|
return super().keyPressEvent(event)
|
|
|
|
|
|
|
|
|
|
|
|
# 其他情况下,阻止回车事件传播
|
|
|
|
|
|
event.accept() # 消费掉这个事件
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
# 其他键位事件交给父类处理
|
2025-06-24 16:33:33 +08:00
|
|
|
|
super().keyPressEvent(event)
|
|
|
|
|
|
|
|
|
|
|
|
def get_unloading_info(self):
|
|
|
|
|
|
"""获取当前下料信息"""
|
|
|
|
|
|
return {
|
|
|
|
|
|
'tray_code': self.tray_input.text().strip(),
|
|
|
|
|
|
'tier': self.tier_input.text().strip(),
|
|
|
|
|
|
'pallet_type': self.pallet_type_input.currentText().strip(),
|
|
|
|
|
|
'pallet_type_id': self.get_current_pallet_type_id(),
|
|
|
|
|
|
'axis_type': self.axis_value.text().strip(),
|
|
|
|
|
|
'material': self.material_tier_value.text().strip(),
|
|
|
|
|
|
'quantity': self.quantity_value.text().strip(),
|
|
|
|
|
|
'weight': self.weight_value.text().strip()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def set_unloading_info(self, info):
|
|
|
|
|
|
"""设置下料信息"""
|
|
|
|
|
|
if not info:
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
self.tray_input.setText(info.get('tray_code', ''))
|
|
|
|
|
|
self.tier_input.setText(info.get('tier', ''))
|
|
|
|
|
|
|
|
|
|
|
|
# 设置托盘类型
|
|
|
|
|
|
pallet_type = info.get('pallet_type', '')
|
|
|
|
|
|
index = self.pallet_type_input.findText(pallet_type)
|
|
|
|
|
|
if index >= 0:
|
|
|
|
|
|
self.pallet_type_input.setCurrentIndex(index)
|
|
|
|
|
|
|
|
|
|
|
|
# 设置其他信息
|
|
|
|
|
|
self.axis_value.setText(info.get('axis_type', '--'))
|
|
|
|
|
|
self.material_tier_value.setText(info.get('material', '--'))
|
|
|
|
|
|
self.quantity_value.setText(info.get('quantity', '0'))
|
|
|
|
|
|
self.weight_value.setText(info.get('weight', '0 kg'))
|
|
|
|
|
|
|
|
|
|
|
|
# 记录日志
|
|
|
|
|
|
logging.info(f"回显下料信息: 托盘号={info.get('tray_code', '')}, 层数={info.get('tier', '')}")
|
|
|
|
|
|
|
|
|
|
|
|
def accept(self):
|
|
|
|
|
|
"""确认按钮点击事件"""
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 获取输入的值
|
|
|
|
|
|
tray_code = self.tray_input.text().strip()
|
|
|
|
|
|
tier = self.tier_input.text().strip()
|
|
|
|
|
|
pallet_type = self.pallet_type_input.currentText().strip()
|
|
|
|
|
|
|
|
|
|
|
|
# 验证输入
|
|
|
|
|
|
if not tray_code:
|
|
|
|
|
|
QMessageBox.warning(self, "提示", "请输入托盘号")
|
|
|
|
|
|
return
|
|
|
|
|
|
if not tier:
|
|
|
|
|
|
QMessageBox.warning(self, "提示", "请输入层数")
|
|
|
|
|
|
return
|
|
|
|
|
|
if not pallet_type or pallet_type == "请选择":
|
|
|
|
|
|
QMessageBox.warning(self, "提示", "请选择托盘类型")
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
# 获取托盘类型ID并写入寄存器
|
|
|
|
|
|
pallet_type_id = self.get_current_pallet_type_id()
|
|
|
|
|
|
if pallet_type_id is not None:
|
|
|
|
|
|
try:
|
|
|
|
|
|
modbus = ModbusUtils()
|
|
|
|
|
|
client = modbus.get_client()
|
|
|
|
|
|
modbus.write_register_until_success(client, 1, int(pallet_type_id))
|
|
|
|
|
|
logging.info(f"已将托盘类型ID {pallet_type_id} 写入寄存器1")
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logging.error(f"写入托盘类型ID到寄存器失败: {str(e)}")
|
|
|
|
|
|
QMessageBox.critical(self, "Modbus通信错误", f"写入托盘类型ID失败: {str(e)}")
|
|
|
|
|
|
# 即使失败也允许继续,但给与提示
|
|
|
|
|
|
finally:
|
|
|
|
|
|
if 'modbus' in locals() and client:
|
|
|
|
|
|
modbus.close_client(client)
|
|
|
|
|
|
else:
|
|
|
|
|
|
QMessageBox.warning(self, "提示", "无法获取托盘类型ID,请检查配置")
|
|
|
|
|
|
|
|
|
|
|
|
# 保存托盘档案信息
|
|
|
|
|
|
try:
|
|
|
|
|
|
pallet_type_manager = PalletTypeManager.get_instance()
|
|
|
|
|
|
material = self.material_tier_value.text().strip()
|
|
|
|
|
|
pallet_info = {"cc": pallet_type, "cs": tier, "cz": material}
|
|
|
|
|
|
pallet_type_manager.save_pallet_info(tray_code, pallet_info, self.user_id)
|
|
|
|
|
|
logging.info(f"已保存下料托盘信息: {tray_code}, 层数={tier}, 托盘类型={pallet_type}, 材质={material}")
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logging.error(f"保存下料托盘信息失败: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
# 调用父类的accept方法关闭对话框,由主窗口处理后续逻辑
|
|
|
|
|
|
super().accept()
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logging.error(f"下料对话框确认时发生错误: {str(e)}")
|
|
|
|
|
|
QMessageBox.critical(self, "错误", f"确认下料失败: {str(e)}")
|