Compare commits
6 Commits
c26a52d1da
...
cc33d9318d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc33d9318d | ||
|
|
e638b7395d | ||
|
|
a1f9a56781 | ||
|
|
7b0d0a28f2 | ||
|
|
e9f94db1d6 | ||
|
|
935fd44f78 |
5
.gitignore
vendored
5
.gitignore
vendored
@ -11,6 +11,11 @@ __pycache__/
|
|||||||
*.py[cod]
|
*.py[cod]
|
||||||
*$py.class
|
*$py.class
|
||||||
|
|
||||||
|
# 确保所有层级的__pycache__目录都被忽略
|
||||||
|
**/__pycache__/
|
||||||
|
*/__pycache__/
|
||||||
|
*/**/__pycache__/
|
||||||
|
|
||||||
# IDE相关
|
# IDE相关
|
||||||
.idea/
|
.idea/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -4,18 +4,34 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"features": {
|
"features": {
|
||||||
"enable_serial_ports": false,
|
"enable_serial_ports": false,
|
||||||
"enable_keyboard_listener": true,
|
"enable_keyboard_listener": false,
|
||||||
"enable_camera": false
|
"enable_camera": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"database": {
|
"database": {
|
||||||
"type": "sqlite",
|
"default": "sqlite",
|
||||||
"path": "db/jtDB.db",
|
"sources": {
|
||||||
"host": "",
|
"sqlite": {
|
||||||
"port": "",
|
"path": "db/jtDB.db",
|
||||||
"user": "",
|
"description": "默认SQLite数据库"
|
||||||
"password": "",
|
},
|
||||||
"name": ""
|
"postgresql": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": "5432",
|
||||||
|
"user": "postgres",
|
||||||
|
"password": "",
|
||||||
|
"name": "jtDB",
|
||||||
|
"description": "PostgreSQL数据库"
|
||||||
|
},
|
||||||
|
"mysql": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": "3306",
|
||||||
|
"user": "root",
|
||||||
|
"password": "",
|
||||||
|
"name": "jtDB",
|
||||||
|
"description": "MySQL数据库"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"camera": {
|
"camera": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
|
|||||||
@ -403,6 +403,7 @@ class InspectionDAO:
|
|||||||
tray_id,
|
tray_id,
|
||||||
COALESCE(axis_package_id, '') as axis_package_id,
|
COALESCE(axis_package_id, '') as axis_package_id,
|
||||||
COALESCE(weight, 0) as weight,
|
COALESCE(weight, 0) as weight,
|
||||||
|
COALESCE(net_weight, 0) as net_weight,
|
||||||
STRFTIME('%Y-%m-%d %H:%M:%S', pack_time) as pack_time
|
STRFTIME('%Y-%m-%d %H:%M:%S', pack_time) as pack_time
|
||||||
FROM inspection_pack_data
|
FROM inspection_pack_data
|
||||||
WHERE tray_id = ?
|
WHERE tray_id = ?
|
||||||
@ -416,7 +417,7 @@ class InspectionDAO:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"获取包装记录失败: {str(e)}")
|
logging.error(f"获取包装记录失败: {str(e)}")
|
||||||
return []
|
return []
|
||||||
def save_package_record(self, order_id, tray_id, label_value, weight_value, finish_time):
|
def save_package_record(self, order_id, tray_id, label_value, weight_value,net_weight_value, finish_time):
|
||||||
"""保存包装记录
|
"""保存包装记录
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -429,10 +430,10 @@ class InspectionDAO:
|
|||||||
# TODO:调用接口,获取到工程号对应的其他信息,比如材质,规格,后续完成
|
# TODO:调用接口,获取到工程号对应的其他信息,比如材质,规格,后续完成
|
||||||
try:
|
try:
|
||||||
sql = """
|
sql = """
|
||||||
INSERT INTO inspection_pack_data (order_id, tray_id, axis_package_id, weight, pack_time, create_time, create_by, update_time, update_by, is_deleted)
|
INSERT INTO inspection_pack_data (order_id, tray_id, axis_package_id, weight, net_weight, pack_time, create_time, create_by, update_time, update_by, is_deleted)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
"""
|
"""
|
||||||
params = (order_id, tray_id, label_value, weight_value, finish_time, datetime.now(), 'system', datetime.now(), 'system', False)
|
params = (order_id, tray_id, label_value, weight_value, net_weight_value, finish_time, datetime.now(), 'system', datetime.now(), 'system', False)
|
||||||
self.db.cursor.execute(sql, params)
|
self.db.cursor.execute(sql, params)
|
||||||
self.db.conn.commit()
|
self.db.conn.commit()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
BIN
db/jtDB.db
BIN
db/jtDB.db
Binary file not shown.
@ -2,12 +2,12 @@ from pymodbus.client import ModbusTcpClient
|
|||||||
|
|
||||||
client = ModbusTcpClient('localhost', port=5020)
|
client = ModbusTcpClient('localhost', port=5020)
|
||||||
client.connect()
|
client.connect()
|
||||||
client.write_registers(address=11, values=[112])
|
# client.write_registers(address=11, values=[110])
|
||||||
# client.write_registers(address=6, values=[1])
|
# client.write_registers(address=6, values=[1])
|
||||||
# client.write_registers(address=5, values=[16])
|
# client.write_registers(address=5, values=[16])
|
||||||
# client.write_registers(address=13, values=[1])
|
client.write_registers(address=13, values=[1])
|
||||||
|
|
||||||
|
|
||||||
result = client.read_holding_registers(address=4, count=1)
|
result = client.read_holding_registers(address=13, count=1)
|
||||||
print(result.registers[0],"123===")
|
print(result.registers[0],"123===")
|
||||||
client.close()
|
client.close()
|
||||||
12
main.py
12
main.py
@ -179,8 +179,13 @@ def main():
|
|||||||
# 创建db目录(如果不存在)
|
# 创建db目录(如果不存在)
|
||||||
os.makedirs('db', exist_ok=True)
|
os.makedirs('db', exist_ok=True)
|
||||||
|
|
||||||
|
# 从配置获取SQLite数据库路径
|
||||||
|
config_loader = ConfigLoader.get_instance()
|
||||||
|
sqlite_config = config_loader.get_database_config('sqlite')
|
||||||
|
sqlite_db_path = sqlite_config.get('path', 'db/jtDB.db')
|
||||||
|
|
||||||
# 检查数据库是否存在,如果不存在则初始化
|
# 检查数据库是否存在,如果不存在则初始化
|
||||||
if not os.path.exists('db/jtDB.db'):
|
if not os.path.exists(sqlite_db_path):
|
||||||
from utils.init_db import init_database
|
from utils.init_db import init_database
|
||||||
init_database()
|
init_database()
|
||||||
logging.info("初始化数据库完成")
|
logging.info("初始化数据库完成")
|
||||||
@ -190,6 +195,11 @@ def main():
|
|||||||
|
|
||||||
exit_code = app.exec()
|
exit_code = app.exec()
|
||||||
logging.info(f"应用程序退出,退出码: {exit_code}")
|
logging.info(f"应用程序退出,退出码: {exit_code}")
|
||||||
|
|
||||||
|
# 关闭所有数据库连接
|
||||||
|
from utils.sql_utils import SQLUtils
|
||||||
|
SQLUtils.close_all_connections()
|
||||||
|
|
||||||
sys.exit(exit_code)
|
sys.exit(exit_code)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Binary file not shown.
@ -285,13 +285,13 @@ class MainWindowUI(QMainWindow):
|
|||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# self.input_button = QPushButton("上料")
|
self.input_button = QPushButton("上料")
|
||||||
# self.input_button.setFont(self.normal_font)
|
self.input_button.setFont(self.normal_font)
|
||||||
# self.input_button.setStyleSheet(button_style + "background-color: #e3f2fd; border: 1px solid #2196f3;")
|
self.input_button.setStyleSheet(button_style + "background-color: #e3f2fd; border: 1px solid #2196f3;")
|
||||||
|
|
||||||
# self.output_button = QPushButton("下料")
|
self.output_button = QPushButton("下料")
|
||||||
# self.output_button.setFont(self.normal_font)
|
self.output_button.setFont(self.normal_font)
|
||||||
# self.output_button.setStyleSheet(button_style + "background-color: #fff8e1; border: 1px solid #ffc107;")
|
self.output_button.setStyleSheet(button_style + "background-color: #fff8e1; border: 1px solid #ffc107;")
|
||||||
|
|
||||||
self.start_button = QPushButton("开始")
|
self.start_button = QPushButton("开始")
|
||||||
self.start_button.setFont(self.normal_font)
|
self.start_button.setFont(self.normal_font)
|
||||||
@ -302,10 +302,10 @@ class MainWindowUI(QMainWindow):
|
|||||||
self.stop_button.setStyleSheet(button_style + "background-color: #ffebee; border: 1px solid #f44336;")
|
self.stop_button.setStyleSheet(button_style + "background-color: #ffebee; border: 1px solid #f44336;")
|
||||||
|
|
||||||
# 使用网格布局排列按钮
|
# 使用网格布局排列按钮
|
||||||
# self.button_layout.addWidget(self.input_button, 0, 0)
|
self.button_layout.addWidget(self.input_button, 0, 0)
|
||||||
# self.button_layout.addWidget(self.output_button, 0, 1)
|
self.button_layout.addWidget(self.output_button, 0, 1)
|
||||||
self.button_layout.addWidget(self.start_button, 0, 1)
|
self.button_layout.addWidget(self.start_button, 0, 2)
|
||||||
self.button_layout.addWidget(self.stop_button, 0, 2)
|
self.button_layout.addWidget(self.stop_button, 0, 3)
|
||||||
|
|
||||||
self.control_layout.addWidget(self.button_container)
|
self.control_layout.addWidget(self.button_container)
|
||||||
|
|
||||||
@ -501,13 +501,13 @@ class MainWindowUI(QMainWindow):
|
|||||||
self.record_layout.addWidget(self.record_title)
|
self.record_layout.addWidget(self.record_title)
|
||||||
|
|
||||||
# 创建表格
|
# 创建表格
|
||||||
self.record_table = QTableWidget(14, 8) # 14行7列:序号、订单、品名、规格、托号、轴包装号、重量
|
self.record_table = QTableWidget(14, 9) # 14行9列:序号、订单、品名、规格、托号、轴包装号、重量、净重、完成时间
|
||||||
|
|
||||||
# 应用通用表格设置
|
# 应用通用表格设置
|
||||||
self.setup_table_common(self.record_table)
|
self.setup_table_common(self.record_table)
|
||||||
|
|
||||||
# 设置列标题
|
# 设置列标题
|
||||||
record_headers = ["序号", "订单", "品名", "规格", "托号", "轴包装号", "重量", "完成时间"]
|
record_headers = ["序号", "订单", "品名", "规格", "托号", "轴包装号", "毛重", "净重", "完成时间"]
|
||||||
for col, header in enumerate(record_headers):
|
for col, header in enumerate(record_headers):
|
||||||
self.record_table.setItem(0, col, self.create_header_item(header))
|
self.record_table.setItem(0, col, self.create_header_item(header))
|
||||||
|
|
||||||
@ -520,7 +520,7 @@ class MainWindowUI(QMainWindow):
|
|||||||
self.record_table.setRowHeight(row, 35)
|
self.record_table.setRowHeight(row, 35)
|
||||||
|
|
||||||
# 设置列宽
|
# 设置列宽
|
||||||
column_widths = [70, 220, 160, 160, 160, 160, 160, 190] # 各列的默认宽度
|
column_widths = [70, 200, 130, 130, 160, 120, 120, 120, 160] # 各列的默认宽度
|
||||||
for col, width in enumerate(column_widths):
|
for col, width in enumerate(column_widths):
|
||||||
self.record_table.setColumnWidth(col, width)
|
self.record_table.setColumnWidth(col, width)
|
||||||
|
|
||||||
@ -593,7 +593,7 @@ class MainWindowUI(QMainWindow):
|
|||||||
self.inspection_headers = self.inspection_headers[:columns]
|
self.inspection_headers = self.inspection_headers[:columns]
|
||||||
|
|
||||||
# 计算总列数
|
# 计算总列数
|
||||||
total_columns = 2 + self.inspection_columns + 2 # 上料2列 + 检验N列 + 包装2列
|
total_columns = 2 + self.inspection_columns + 3 # 上料2列 + 检验N列 + 包装3列
|
||||||
self.process_table.setColumnCount(total_columns)
|
self.process_table.setColumnCount(total_columns)
|
||||||
|
|
||||||
# 重新设置列宽
|
# 重新设置列宽
|
||||||
@ -614,9 +614,9 @@ class MainWindowUI(QMainWindow):
|
|||||||
self.process_table.setSpan(0, 2, 1, self.inspection_columns)
|
self.process_table.setSpan(0, 2, 1, self.inspection_columns)
|
||||||
self.process_table.setItem(0, 2, self.create_header_item("检验"))
|
self.process_table.setItem(0, 2, self.create_header_item("检验"))
|
||||||
|
|
||||||
# 包装区域(2列)
|
# 包装区域(3列)
|
||||||
packaging_start_col = 2 + self.inspection_columns
|
packaging_start_col = 2 + self.inspection_columns
|
||||||
self.process_table.setSpan(0, packaging_start_col, 1, 2)
|
self.process_table.setSpan(0, packaging_start_col, 1, 3)
|
||||||
self.process_table.setItem(0, packaging_start_col, self.create_header_item("包装"))
|
self.process_table.setItem(0, packaging_start_col, self.create_header_item("包装"))
|
||||||
|
|
||||||
# 第二行:列标题
|
# 第二行:列标题
|
||||||
@ -636,7 +636,7 @@ class MainWindowUI(QMainWindow):
|
|||||||
self.process_table.setItem(1, 2 + i, self.create_header_item(header_text))
|
self.process_table.setItem(1, 2 + i, self.create_header_item(header_text))
|
||||||
|
|
||||||
# 包装区域列标题
|
# 包装区域列标题
|
||||||
packaging_headers = ["贴标", "称重"]
|
packaging_headers = ["贴标", "毛重", "净重"]
|
||||||
for i, header in enumerate(packaging_headers):
|
for i, header in enumerate(packaging_headers):
|
||||||
self.process_table.setItem(1, packaging_start_col + i, self.create_header_item(header))
|
self.process_table.setItem(1, packaging_start_col + i, self.create_header_item(header))
|
||||||
|
|
||||||
@ -653,4 +653,5 @@ class MainWindowUI(QMainWindow):
|
|||||||
# 包装区域列宽
|
# 包装区域列宽
|
||||||
packaging_start_col = 2 + self.inspection_columns
|
packaging_start_col = 2 + self.inspection_columns
|
||||||
self.process_table.setColumnWidth(packaging_start_col, 140) # 贴标
|
self.process_table.setColumnWidth(packaging_start_col, 140) # 贴标
|
||||||
self.process_table.setColumnWidth(packaging_start_col + 1, 140) # 称重
|
self.process_table.setColumnWidth(packaging_start_col + 1, 140) # 毛重
|
||||||
|
self.process_table.setColumnWidth(packaging_start_col + 2, 140) # 净重
|
||||||
@ -205,25 +205,31 @@ class SettingsUI(QWidget):
|
|||||||
self.database_layout = QVBoxLayout(self.database_tab)
|
self.database_layout = QVBoxLayout(self.database_tab)
|
||||||
self.database_layout.setContentsMargins(20, 20, 20, 20)
|
self.database_layout.setContentsMargins(20, 20, 20, 20)
|
||||||
|
|
||||||
# 数据库类型选择
|
# 数据源类型选择
|
||||||
self.db_type_group = QGroupBox("数据库类型")
|
self.db_type_group = QGroupBox("数据源类型")
|
||||||
self.db_type_group.setFont(self.normal_font)
|
self.db_type_group.setFont(self.normal_font)
|
||||||
self.db_type_layout = QHBoxLayout()
|
self.db_type_layout = QHBoxLayout()
|
||||||
|
|
||||||
self.sqlite_radio = QCheckBox("SQLite")
|
self.db_type_combo = QComboBox()
|
||||||
self.sqlite_radio.setFont(self.normal_font)
|
self.db_type_combo.setFont(self.normal_font)
|
||||||
self.sqlite_radio.setChecked(True)
|
self.db_type_combo.addItem("SQLite")
|
||||||
|
self.db_type_combo.addItem("PostgreSQL")
|
||||||
|
self.db_type_combo.addItem("MySQL")
|
||||||
|
|
||||||
self.pgsql_radio = QCheckBox("PostgreSQL")
|
self.db_type_layout.addWidget(QLabel("当前配置类型:"))
|
||||||
self.pgsql_radio.setFont(self.normal_font)
|
self.db_type_layout.addWidget(self.db_type_combo)
|
||||||
|
|
||||||
self.mysql_radio = QCheckBox("MySQL")
|
|
||||||
self.mysql_radio.setFont(self.normal_font)
|
|
||||||
|
|
||||||
self.db_type_layout.addWidget(self.sqlite_radio)
|
|
||||||
self.db_type_layout.addWidget(self.pgsql_radio)
|
|
||||||
self.db_type_layout.addWidget(self.mysql_radio)
|
|
||||||
self.db_type_layout.addStretch(1)
|
self.db_type_layout.addStretch(1)
|
||||||
|
|
||||||
|
# 添加当前使用的数据源选择
|
||||||
|
self.current_source_label = QLabel("当前使用的数据源:")
|
||||||
|
self.current_source_label.setFont(self.normal_font)
|
||||||
|
self.current_source_combo = QComboBox()
|
||||||
|
self.current_source_combo.setFont(self.normal_font)
|
||||||
|
self.current_source_combo.addItems(["SQLite", "PostgreSQL", "MySQL"])
|
||||||
|
|
||||||
|
self.db_type_layout.addWidget(self.current_source_label)
|
||||||
|
self.db_type_layout.addWidget(self.current_source_combo)
|
||||||
|
|
||||||
self.db_type_group.setLayout(self.db_type_layout)
|
self.db_type_group.setLayout(self.db_type_layout)
|
||||||
self.database_layout.addWidget(self.db_type_group)
|
self.database_layout.addWidget(self.db_type_group)
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -32,6 +32,9 @@ class ConfigLoader:
|
|||||||
with open(self.config_file, 'r', encoding='utf-8') as f:
|
with open(self.config_file, 'r', encoding='utf-8') as f:
|
||||||
self.config = json.load(f)
|
self.config = json.load(f)
|
||||||
logging.info(f"已加载配置文件: {self.config_file}")
|
logging.info(f"已加载配置文件: {self.config_file}")
|
||||||
|
|
||||||
|
# 检查并升级配置文件结构(兼容旧版本的配置)
|
||||||
|
self._upgrade_config_if_needed()
|
||||||
else:
|
else:
|
||||||
# 创建默认配置
|
# 创建默认配置
|
||||||
self.config = {
|
self.config = {
|
||||||
@ -40,17 +43,50 @@ class ConfigLoader:
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"features": {
|
"features": {
|
||||||
"enable_serial_ports": False,
|
"enable_serial_ports": False,
|
||||||
"enable_keyboard_listener": False
|
"enable_keyboard_listener": False,
|
||||||
|
"enable_camera": False
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"database": {
|
"database": {
|
||||||
"type": "sqlite",
|
"current": "sqlite",
|
||||||
"path": "db/jtDB.db",
|
"sources": {
|
||||||
"host": "",
|
"sqlite": {
|
||||||
"port": "",
|
"path": "db/jtDB.db",
|
||||||
"user": "",
|
"description": "默认SQLite数据库"
|
||||||
"password": "",
|
},
|
||||||
"name": ""
|
"postgresql": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": "5432",
|
||||||
|
"user": "postgres",
|
||||||
|
"password": "",
|
||||||
|
"name": "jtDB",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"mysql": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": "3306",
|
||||||
|
"user": "root",
|
||||||
|
"password": "",
|
||||||
|
"name": "jtDB",
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"camera": {
|
||||||
|
"enabled": False,
|
||||||
|
"default_exposure": 20000,
|
||||||
|
"default_gain": 10,
|
||||||
|
"default_framerate": 30
|
||||||
|
},
|
||||||
|
"modbus": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": "5020"
|
||||||
|
},
|
||||||
|
"serial": {
|
||||||
|
"keyboard": {
|
||||||
|
"trigger_key": "Key.page_up",
|
||||||
|
"enabled": False
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,11 +102,87 @@ class ConfigLoader:
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"features": {
|
"features": {
|
||||||
"enable_serial_ports": False,
|
"enable_serial_ports": False,
|
||||||
"enable_keyboard_listener": False
|
"enable_keyboard_listener": False,
|
||||||
|
"enable_camera": False
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"database": {
|
||||||
|
"current": "sqlite",
|
||||||
|
"sources": {
|
||||||
|
"sqlite": {
|
||||||
|
"path": "db/jtDB.db",
|
||||||
|
"description": "默认SQLite数据库"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _upgrade_config_if_needed(self):
|
||||||
|
"""升级配置文件结构(兼容旧版本的配置)"""
|
||||||
|
try:
|
||||||
|
# 检查数据库配置是否需要升级
|
||||||
|
if 'database' in self.config:
|
||||||
|
db_config = self.config['database']
|
||||||
|
|
||||||
|
# 旧版本配置结构检查
|
||||||
|
if 'type' in db_config and 'sources' not in db_config:
|
||||||
|
logging.info("检测到旧版本的数据库配置,正在升级...")
|
||||||
|
|
||||||
|
# 获取旧配置
|
||||||
|
db_type = db_config.get('type', 'sqlite')
|
||||||
|
|
||||||
|
# 创建新的配置结构
|
||||||
|
new_db_config = {
|
||||||
|
"default": db_type,
|
||||||
|
"sources": {}
|
||||||
|
}
|
||||||
|
|
||||||
|
# 转移旧配置到新结构
|
||||||
|
if db_type == 'sqlite':
|
||||||
|
new_db_config['sources']['sqlite'] = {
|
||||||
|
"path": db_config.get('path', 'db/jtDB.db'),
|
||||||
|
"description": "从旧版本升级的SQLite数据库"
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
new_db_config['sources'][db_type] = {
|
||||||
|
"host": db_config.get('host', 'localhost'),
|
||||||
|
"port": db_config.get('port', '5432' if db_type == 'postgresql' else '3306'),
|
||||||
|
"user": db_config.get('user', ''),
|
||||||
|
"password": db_config.get('password', ''),
|
||||||
|
"name": db_config.get('name', 'jtDB'),
|
||||||
|
"description": f"从旧版本升级的{db_type}数据库"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 确保至少有一个sqlite配置
|
||||||
|
if 'sqlite' not in new_db_config['sources']:
|
||||||
|
new_db_config['sources']['sqlite'] = {
|
||||||
|
"path": "db/jtDB.db",
|
||||||
|
"description": "默认SQLite数据库"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 更新配置
|
||||||
|
self.config['database'] = new_db_config
|
||||||
|
self.save_config()
|
||||||
|
logging.info("数据库配置已成功升级")
|
||||||
|
|
||||||
|
# 将current改为default
|
||||||
|
if 'current' in db_config and 'default' not in db_config:
|
||||||
|
logging.info("将数据库配置中的'current'改为'default'...")
|
||||||
|
db_config['default'] = db_config.pop('current')
|
||||||
|
self.save_config()
|
||||||
|
|
||||||
|
# 将pgsql改为postgresql
|
||||||
|
if 'sources' in db_config and 'pgsql' in db_config['sources'] and 'postgresql' not in db_config['sources']:
|
||||||
|
logging.info("将数据库配置中的'pgsql'改为'postgresql'...")
|
||||||
|
db_config['sources']['postgresql'] = db_config['sources'].pop('pgsql')
|
||||||
|
# 如果默认值是pgsql,也更新
|
||||||
|
if db_config.get('default') == 'pgsql':
|
||||||
|
db_config['default'] = 'postgresql'
|
||||||
|
self.save_config()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"升级配置文件结构失败: {e}")
|
||||||
|
|
||||||
def save_config(self):
|
def save_config(self):
|
||||||
"""保存配置到文件"""
|
"""保存配置到文件"""
|
||||||
try:
|
try:
|
||||||
@ -163,4 +275,25 @@ class ConfigLoader:
|
|||||||
|
|
||||||
self.config['serial'][key] = config_data
|
self.config['serial'][key] = config_data
|
||||||
# 这里不保存配置,等待调用save_config方法时一并保存
|
# 这里不保存配置,等待调用save_config方法时一并保存
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def get_database_config(self, db_type=None):
|
||||||
|
"""
|
||||||
|
获取指定类型的数据库配置
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db_type: 数据库类型,如'sqlite', 'postgresql', 'mysql'等,不指定则使用默认配置
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: 数据库配置
|
||||||
|
"""
|
||||||
|
# 如果未指定数据库类型,使用当前设置的类型
|
||||||
|
if db_type is None:
|
||||||
|
db_type = self.get_value('database.default', 'sqlite')
|
||||||
|
|
||||||
|
# 处理pgsql和postgresql兼容
|
||||||
|
if db_type == 'pgsql':
|
||||||
|
db_type = 'postgresql'
|
||||||
|
|
||||||
|
# 获取数据库配置
|
||||||
|
return self.get_value(f'database.sources.{db_type}', {})
|
||||||
@ -2,9 +2,20 @@ from utils.sql_utils import SQLUtils
|
|||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
from utils.config_loader import ConfigLoader
|
||||||
|
|
||||||
def init_database():
|
def init_database():
|
||||||
db = SQLUtils('sqlite', database='db/jtDB.db')
|
# 获取SQLite数据源的路径
|
||||||
|
config_loader = ConfigLoader.get_instance()
|
||||||
|
sqlite_config = config_loader.get_database_config('sqlite')
|
||||||
|
db_path = sqlite_config.get('path', 'db/jtDB.db')
|
||||||
|
|
||||||
|
# 确保db目录存在
|
||||||
|
db_dir = os.path.dirname(db_path)
|
||||||
|
os.makedirs(db_dir, exist_ok=True)
|
||||||
|
|
||||||
|
logging.info(f"初始化数据库: {db_path}")
|
||||||
|
db = SQLUtils('sqlite', database=db_path)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
db.begin_transaction()
|
db.begin_transaction()
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
import sys
|
import sys
|
||||||
|
import logging
|
||||||
|
from utils.config_loader import ConfigLoader
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import psycopg2
|
import psycopg2
|
||||||
@ -10,27 +12,127 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
sqlite3 = None
|
sqlite3 = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
import mysql.connector
|
||||||
|
except ImportError:
|
||||||
|
mysql = None
|
||||||
|
|
||||||
|
|
||||||
class SQLUtils:
|
class SQLUtils:
|
||||||
def __init__(self, db_type, **kwargs):
|
# 存储连接池,避免重复创建连接
|
||||||
self.db_type = db_type.lower()
|
_connection_pool = {}
|
||||||
|
|
||||||
|
def __init__(self, db_type=None, source_name=None, **kwargs):
|
||||||
|
"""初始化SQLUtils对象
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db_type: 数据库类型 'sqlite', 'postgresql', 'mysql' 之一,如果为None则使用配置文件中的默认数据源
|
||||||
|
source_name: 数据源名称,用于从配置中获取特定的数据源,如'sqlite', 'postgresql', 'mysql'
|
||||||
|
**kwargs: 连接参数,如果没有提供,则使用配置文件中的参数
|
||||||
|
"""
|
||||||
self.conn = None
|
self.conn = None
|
||||||
self.cursor = None
|
self.cursor = None
|
||||||
|
|
||||||
|
# 如果指定了source_name,直接使用该名称的数据源配置
|
||||||
|
if source_name:
|
||||||
|
config_loader = ConfigLoader.get_instance()
|
||||||
|
db_config = config_loader.get_value(f'database.sources.{source_name}', {})
|
||||||
|
if not db_config:
|
||||||
|
raise ValueError(f"未找到数据源配置: {source_name}")
|
||||||
|
|
||||||
|
db_type = source_name # 数据源名称同时也是类型
|
||||||
|
|
||||||
|
if not kwargs: # 如果没有提供连接参数,则使用配置中的参数
|
||||||
|
if source_name == 'sqlite':
|
||||||
|
kwargs = {'database': db_config.get('path', 'db/jtDB.db')}
|
||||||
|
else:
|
||||||
|
kwargs = {
|
||||||
|
'host': db_config.get('host', 'localhost'),
|
||||||
|
'user': db_config.get('user', ''),
|
||||||
|
'password': db_config.get('password', ''),
|
||||||
|
'database': db_config.get('name', 'jtDB')
|
||||||
|
}
|
||||||
|
if 'port' in db_config and db_config['port']:
|
||||||
|
kwargs['port'] = int(db_config['port'])
|
||||||
|
|
||||||
|
# 如果没有指定数据库类型和数据源名称,则使用配置中的默认数据源
|
||||||
|
elif db_type is None:
|
||||||
|
config_loader = ConfigLoader.get_instance()
|
||||||
|
default_source = config_loader.get_value('database.default', 'sqlite')
|
||||||
|
|
||||||
|
# 如果没有提供连接参数,则从配置文件获取
|
||||||
|
if not kwargs:
|
||||||
|
db_config = config_loader.get_database_config(default_source)
|
||||||
|
if default_source == 'sqlite':
|
||||||
|
kwargs = {'database': db_config.get('path', 'db/jtDB.db')}
|
||||||
|
else:
|
||||||
|
kwargs = {
|
||||||
|
'host': db_config.get('host', 'localhost'),
|
||||||
|
'user': db_config.get('user', ''),
|
||||||
|
'password': db_config.get('password', ''),
|
||||||
|
'database': db_config.get('name', 'jtDB')
|
||||||
|
}
|
||||||
|
if 'port' in db_config and db_config['port']:
|
||||||
|
kwargs['port'] = int(db_config['port'])
|
||||||
|
|
||||||
|
db_type = default_source
|
||||||
|
|
||||||
|
self.db_type = db_type.lower()
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
|
self.source_name = source_name or self.db_type
|
||||||
|
|
||||||
|
# 尝试从连接池获取连接,如果没有则创建新连接
|
||||||
|
self._get_connection()
|
||||||
|
|
||||||
|
def _get_connection(self):
|
||||||
|
"""从连接池获取连接,如果没有则创建新连接"""
|
||||||
|
# 创建连接键,包含数据库类型和连接参数
|
||||||
|
conn_key = f"{self.db_type}:{str(self.kwargs)}"
|
||||||
|
|
||||||
|
# 检查连接池中是否已有此连接
|
||||||
|
if conn_key in SQLUtils._connection_pool:
|
||||||
|
try:
|
||||||
|
# 尝试执行简单查询,确认连接有效
|
||||||
|
conn, cursor = SQLUtils._connection_pool[conn_key]
|
||||||
|
cursor.execute("SELECT 1")
|
||||||
|
# 连接有效,直接使用
|
||||||
|
self.conn = conn
|
||||||
|
self.cursor = cursor
|
||||||
|
return
|
||||||
|
except Exception:
|
||||||
|
# 连接已失效,从连接池移除
|
||||||
|
del SQLUtils._connection_pool[conn_key]
|
||||||
|
|
||||||
|
# 创建新连接
|
||||||
self.connect()
|
self.connect()
|
||||||
|
|
||||||
|
# 将新连接添加到连接池
|
||||||
|
if self.conn and self.cursor:
|
||||||
|
SQLUtils._connection_pool[conn_key] = (self.conn, self.cursor)
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
if self.db_type == 'pgsql' or self.db_type == 'postgresql':
|
"""连接到数据库"""
|
||||||
if not psycopg2:
|
try:
|
||||||
raise ImportError('psycopg2 is not installed')
|
if self.db_type in ['pgsql', 'postgresql']:
|
||||||
self.conn = psycopg2.connect(**self.kwargs)
|
if not psycopg2:
|
||||||
elif self.db_type == 'sqlite' or self.db_type == 'sqlite3':
|
raise ImportError('psycopg2 is not installed')
|
||||||
if not sqlite3:
|
self.conn = psycopg2.connect(**self.kwargs)
|
||||||
raise ImportError('sqlite3 is not installed')
|
elif self.db_type in ['sqlite', 'sqlite3']:
|
||||||
self.conn = sqlite3.connect(self.kwargs.get('database', ':memory:'))
|
if not sqlite3:
|
||||||
else:
|
raise ImportError('sqlite3 is not installed')
|
||||||
raise ValueError(f'Unsupported db_type: {self.db_type}')
|
self.conn = sqlite3.connect(self.kwargs.get('database', ':memory:'))
|
||||||
self.cursor = self.conn.cursor()
|
elif self.db_type == 'mysql':
|
||||||
|
if not mysql:
|
||||||
|
raise ImportError('mysql.connector is not installed')
|
||||||
|
self.conn = mysql.connector.connect(**self.kwargs)
|
||||||
|
else:
|
||||||
|
raise ValueError(f'不支持的数据库类型: {self.db_type}')
|
||||||
|
|
||||||
|
self.cursor = self.conn.cursor()
|
||||||
|
logging.debug(f"成功连接到数据库: {self.db_type}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"连接数据库失败: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
def execute_query(self, sql, params=None):
|
def execute_query(self, sql, params=None):
|
||||||
if params is None:
|
if params is None:
|
||||||
@ -72,7 +174,36 @@ class SQLUtils:
|
|||||||
return self.cursor.fetchall()
|
return self.cursor.fetchall()
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
if self.cursor:
|
"""关闭连接(实际上是将连接返回到连接池)"""
|
||||||
self.cursor.close()
|
# 这里不再实际关闭连接,让连接池管理连接生命周期
|
||||||
if self.conn:
|
pass
|
||||||
self.conn.close()
|
|
||||||
|
@staticmethod
|
||||||
|
def close_all_connections():
|
||||||
|
"""关闭所有连接池中的连接"""
|
||||||
|
for conn, cursor in SQLUtils._connection_pool.values():
|
||||||
|
try:
|
||||||
|
if cursor:
|
||||||
|
cursor.close()
|
||||||
|
if conn:
|
||||||
|
conn.close()
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"关闭数据库连接失败: {e}")
|
||||||
|
|
||||||
|
SQLUtils._connection_pool.clear()
|
||||||
|
logging.info("已关闭所有数据库连接")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_sqlite_connection():
|
||||||
|
"""获取SQLite连接"""
|
||||||
|
return SQLUtils(source_name='sqlite')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_postgresql_connection():
|
||||||
|
"""获取PostgreSQL连接"""
|
||||||
|
return SQLUtils(source_name='postgresql')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_mysql_connection():
|
||||||
|
"""获取MySQL连接"""
|
||||||
|
return SQLUtils(source_name='mysql')
|
||||||
Binary file not shown.
Binary file not shown.
@ -10,7 +10,8 @@ import threading
|
|||||||
def check_user_login(user_id, password):
|
def check_user_login(user_id, password):
|
||||||
"""验证用户登录"""
|
"""验证用户登录"""
|
||||||
try:
|
try:
|
||||||
db = SQLUtils('sqlite', database='db/jtDB.db')
|
# 始终使用SQLite数据源验证登录
|
||||||
|
db = SQLUtils(source_name='sqlite')
|
||||||
db.execute_query("SELECT id FROM user WHERE username = ? AND password = ? AND is_deleted = 0", (user_id, password))
|
db.execute_query("SELECT id FROM user WHERE username = ? AND password = ? AND is_deleted = 0", (user_id, password))
|
||||||
result = db.fetchone()
|
result = db.fetchone()
|
||||||
db.close()
|
db.close()
|
||||||
@ -22,7 +23,8 @@ def check_user_login(user_id, password):
|
|||||||
def get_user_info(user_id):
|
def get_user_info(user_id):
|
||||||
"""获取用户信息"""
|
"""获取用户信息"""
|
||||||
try:
|
try:
|
||||||
db = SQLUtils('sqlite', database='db/jtDB.db')
|
# 始终使用SQLite数据源获取用户信息
|
||||||
|
db = SQLUtils(source_name='sqlite')
|
||||||
db.execute_query("SELECT username, 'Default Corp', 1, 1 FROM user WHERE username = ?", (user_id,))
|
db.execute_query("SELECT username, 'Default Corp', 1, 1 FROM user WHERE username = ?", (user_id,))
|
||||||
result = db.fetchone()
|
result = db.fetchone()
|
||||||
db.close()
|
db.close()
|
||||||
|
|||||||
@ -243,8 +243,8 @@ class MainWindow(MainWindowUI):
|
|||||||
self.tray_edit.activated.connect(self.load_finished_inspection_data) # 当用户选择一项时触发
|
self.tray_edit.activated.connect(self.load_finished_inspection_data) # 当用户选择一项时触发
|
||||||
|
|
||||||
# 连接按钮事件
|
# 连接按钮事件
|
||||||
# self.input_button.clicked.connect(self.handle_input)
|
self.input_button.clicked.connect(self.handle_input)
|
||||||
# self.output_button.clicked.connect(self.handle_output)
|
self.output_button.clicked.connect(self.handle_output)
|
||||||
self.start_button.clicked.connect(self.handle_start)
|
self.start_button.clicked.connect(self.handle_start)
|
||||||
self.stop_button.clicked.connect(self.handle_stop)
|
self.stop_button.clicked.connect(self.handle_stop)
|
||||||
|
|
||||||
@ -753,7 +753,7 @@ class MainWindow(MainWindowUI):
|
|||||||
inspection_dao.save_inspection_data(order_id, data)
|
inspection_dao.save_inspection_data(order_id, data)
|
||||||
|
|
||||||
# 为贴标和称重也创建空记录
|
# 为贴标和称重也创建空记录
|
||||||
for position in [11, 12]: # 11是贴标,12是称重
|
for position in [11, 12, 13]: # 11是贴标,12是毛重,13是净重
|
||||||
data = [{
|
data = [{
|
||||||
'position': position,
|
'position': position,
|
||||||
'config_id': position,
|
'config_id': position,
|
||||||
@ -878,13 +878,21 @@ class MainWindow(MainWindowUI):
|
|||||||
self.save_inspection_data(order_id, tray_id, 11, 11, value, status)
|
self.save_inspection_data(order_id, tray_id, 11, 11, value, status)
|
||||||
|
|
||||||
elif column == packaging_start_col + 1:
|
elif column == packaging_start_col + 1:
|
||||||
# 称重列
|
# 毛重列
|
||||||
data_type = "称重"
|
data_type = "毛重"
|
||||||
self.statusBar().showMessage(f"正在保存称重数据: {value}", 1000)
|
self.statusBar().showMessage(f"正在保存称重数据: {value}", 1000)
|
||||||
# 设置单元格颜色为通过
|
# 设置单元格颜色为通过
|
||||||
cell_item.setBackground(QBrush(QColor("#c8e6c9"))) # 浅绿色
|
cell_item.setBackground(QBrush(QColor("#c8e6c9"))) # 浅绿色
|
||||||
# 保存称重数据,position和config_id都是12
|
# 保存毛重数据,position和config_id都是12
|
||||||
self.save_inspection_data(order_id, tray_id, 12, 12, value, status)
|
self.save_inspection_data(order_id, tray_id, 12, 12, value, status)
|
||||||
|
elif column == packaging_start_col + 2:
|
||||||
|
# 净重列
|
||||||
|
data_type = "净重"
|
||||||
|
self.statusBar().showMessage(f"正在保存净重数据: {value}", 1000)
|
||||||
|
# 设置单元格颜色为通过
|
||||||
|
cell_item.setBackground(QBrush(QColor("#c8e6c9"))) # 浅绿色
|
||||||
|
# 保存净重数据,position和config_id都是13
|
||||||
|
self.save_inspection_data(order_id, tray_id, 13, 13, value, status)
|
||||||
|
|
||||||
# 记录详细日志
|
# 记录详细日志
|
||||||
logging.info(f"处理单元格变更: 行={row}, 列={column}, 类型={data_type}, 工程号={order_id}, 值={value}, 状态={status}")
|
logging.info(f"处理单元格变更: 行={row}, 列={column}, 类型={data_type}, 工程号={order_id}, 值={value}, 状态={status}")
|
||||||
@ -1090,6 +1098,10 @@ class MainWindow(MainWindowUI):
|
|||||||
# 称重列索引 = 2(序号和工程号) + 检验列数 + 1(贴标)
|
# 称重列索引 = 2(序号和工程号) + 检验列数 + 1(贴标)
|
||||||
weight_col = 2 + len(enabled_configs) + 1
|
weight_col = 2 + len(enabled_configs) + 1
|
||||||
self.process_table.setItem(row_idx, weight_col, QTableWidgetItem(str(value)))
|
self.process_table.setItem(row_idx, weight_col, QTableWidgetItem(str(value)))
|
||||||
|
elif position == 13: # 净重
|
||||||
|
# 净重列索引 = 2(序号和工程号) + 检验列数 + 2(贴标和称重)
|
||||||
|
net_weight_col = 2 + len(enabled_configs) + 2
|
||||||
|
self.process_table.setItem(row_idx, net_weight_col, QTableWidgetItem(str(value)))
|
||||||
row_idx += 1
|
row_idx += 1
|
||||||
|
|
||||||
# 设置表格为可编辑状态
|
# 设置表格为可编辑状态
|
||||||
@ -1129,12 +1141,14 @@ class MainWindow(MainWindowUI):
|
|||||||
# 从检验数据中获取贴标和称重数据
|
# 从检验数据中获取贴标和称重数据
|
||||||
label_value = ""
|
label_value = ""
|
||||||
weight_value = ""
|
weight_value = ""
|
||||||
|
net_weight_value = ""
|
||||||
for item in inspection_data:
|
for item in inspection_data:
|
||||||
if item['position'] == 11: # 贴标
|
if item['position'] == 11: # 贴标
|
||||||
label_value = item['value']
|
label_value = item['value']
|
||||||
elif item['position'] == 12: # 称重
|
elif item['position'] == 12: # 称重
|
||||||
weight_value = item['value']
|
weight_value = item['value']
|
||||||
|
elif item['position'] == 13: # 净重
|
||||||
|
net_weight_value = item['value']
|
||||||
|
|
||||||
# 只要贴标字段有值,就可以写入包装记录
|
# 只要贴标字段有值,就可以写入包装记录
|
||||||
if not label_value:
|
if not label_value:
|
||||||
@ -1152,7 +1166,7 @@ class MainWindow(MainWindowUI):
|
|||||||
finish_time = datetime.now()
|
finish_time = datetime.now()
|
||||||
|
|
||||||
# 将数据写入到数据库表 inspection_pack_data
|
# 将数据写入到数据库表 inspection_pack_data
|
||||||
inspection_dao.save_package_record(order_id, tray_id, label_value, weight_value, finish_time)
|
inspection_dao.save_package_record(order_id, tray_id, label_value, weight_value,net_weight_value, finish_time)
|
||||||
|
|
||||||
# 回显数据
|
# 回显数据
|
||||||
self.show_pack_item()
|
self.show_pack_item()
|
||||||
@ -1223,10 +1237,15 @@ class MainWindow(MainWindowUI):
|
|||||||
weight_item.setTextAlignment(Qt.AlignCenter)
|
weight_item.setTextAlignment(Qt.AlignCenter)
|
||||||
self.record_table.setItem(row_index, 6, weight_item)
|
self.record_table.setItem(row_index, 6, weight_item)
|
||||||
|
|
||||||
|
# 净重 - 第8列
|
||||||
|
net_weight_item = QTableWidgetItem(str(item[6]))
|
||||||
|
net_weight_item.setTextAlignment(Qt.AlignCenter)
|
||||||
|
self.record_table.setItem(row_index, 7, net_weight_item)
|
||||||
|
|
||||||
# 包装时间
|
# 包装时间
|
||||||
pack_time = QTableWidgetItem(str(item[6]))
|
pack_time = QTableWidgetItem(str(item[7]))
|
||||||
weight_item.setTextAlignment(Qt.AlignCenter)
|
pack_time.setTextAlignment(Qt.AlignCenter)
|
||||||
self.record_table.setItem(row_index, 7, pack_time)
|
self.record_table.setItem(row_index, 8, pack_time)
|
||||||
# 更新包装记录统计数据
|
# 更新包装记录统计数据
|
||||||
self.update_package_statistics()
|
self.update_package_statistics()
|
||||||
def update_package_statistics(self):
|
def update_package_statistics(self):
|
||||||
@ -1495,6 +1514,8 @@ class MainWindow(MainWindowUI):
|
|||||||
|
|
||||||
# 计算称重列索引 - 称重位置在检验列之后的第二列(贴标后面)
|
# 计算称重列索引 - 称重位置在检验列之后的第二列(贴标后面)
|
||||||
weight_col = 2 + len(enabled_configs) + 1
|
weight_col = 2 + len(enabled_configs) + 1
|
||||||
|
# 计算净重列索引 - 净重位置在检验列之后的第三列(称重后面)
|
||||||
|
net_weight_col = 2 + len(enabled_configs) + 2
|
||||||
|
|
||||||
# 获取当前选中的行或第一个数据行
|
# 获取当前选中的行或第一个数据行
|
||||||
current_row = self.process_table.currentRow()
|
current_row = self.process_table.currentRow()
|
||||||
@ -1531,6 +1552,15 @@ class MainWindow(MainWindowUI):
|
|||||||
tray_id = self.tray_edit.currentText()
|
tray_id = self.tray_edit.currentText()
|
||||||
self.save_inspection_data(order_id, tray_id, 12, 12, str(weight), "pass")
|
self.save_inspection_data(order_id, tray_id, 12, 12, str(weight), "pass")
|
||||||
|
|
||||||
|
# 保存净重到数据库(毛重-工字轮重量,TODO :先默认工字轮重量为10g后续从接口获取)
|
||||||
|
net_weight = weight - 10
|
||||||
|
self.save_inspection_data(order_id, tray_id, 13, 13, str(net_weight), "pass")
|
||||||
|
|
||||||
|
# 设置净重单元格
|
||||||
|
net_weight_item = QTableWidgetItem(str(net_weight))
|
||||||
|
net_weight_item.setTextAlignment(Qt.AlignCenter)
|
||||||
|
self.process_table.setItem(data_row, net_weight_col, net_weight_item)
|
||||||
|
|
||||||
# 重新连接信号
|
# 重新连接信号
|
||||||
self.process_table.cellChanged.connect(self.handle_inspection_cell_changed)
|
self.process_table.cellChanged.connect(self.handle_inspection_cell_changed)
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
from PySide6.QtWidgets import QMessageBox, QVBoxLayout
|
from PySide6.QtWidgets import QMessageBox, QVBoxLayout
|
||||||
import logging
|
import logging
|
||||||
|
import json
|
||||||
|
import os
|
||||||
from ui.settings_ui import SettingsUI
|
from ui.settings_ui import SettingsUI
|
||||||
from utils.sql_utils import SQLUtils
|
from utils.sql_utils import SQLUtils
|
||||||
from widgets.inspection_settings_widget import InspectionSettingsWidget
|
from widgets.inspection_settings_widget import InspectionSettingsWidget
|
||||||
from widgets.pallet_type_settings_widget import PalletTypeSettingsWidget
|
from widgets.pallet_type_settings_widget import PalletTypeSettingsWidget
|
||||||
|
from utils.config_loader import ConfigLoader
|
||||||
|
|
||||||
class SettingsWidget(SettingsUI):
|
class SettingsWidget(SettingsUI):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
@ -52,19 +55,23 @@ class SettingsWidget(SettingsUI):
|
|||||||
else:
|
else:
|
||||||
logging.error("无法找到pallet_type_layout布局")
|
logging.error("无法找到pallet_type_layout布局")
|
||||||
|
|
||||||
|
# 加载配置文件
|
||||||
|
self.config_loader = ConfigLoader.get_instance()
|
||||||
|
|
||||||
# 连接信号和槽
|
# 连接信号和槽
|
||||||
self.connect_signals()
|
self.connect_signals()
|
||||||
|
|
||||||
# 初始化数据库类型UI状态
|
# 初始化数据库类型UI状态
|
||||||
self.update_db_ui_state()
|
self.load_db_config()
|
||||||
|
|
||||||
logging.info("SettingsWidget初始化完成")
|
logging.info("SettingsWidget初始化完成")
|
||||||
|
|
||||||
def connect_signals(self):
|
def connect_signals(self):
|
||||||
# 数据库类型选择
|
# 数据库类型选择
|
||||||
self.sqlite_radio.toggled.connect(self.update_db_ui_state)
|
self.db_type_combo.currentTextChanged.connect(self.update_db_ui_state)
|
||||||
self.pgsql_radio.toggled.connect(self.update_db_ui_state)
|
|
||||||
self.mysql_radio.toggled.connect(self.update_db_ui_state)
|
# 更新当前使用的数据源
|
||||||
|
self.current_source_combo.currentTextChanged.connect(self.update_default_source)
|
||||||
|
|
||||||
# 按钮动作
|
# 按钮动作
|
||||||
self.test_conn_button.clicked.connect(self.test_connection)
|
self.test_conn_button.clicked.connect(self.test_connection)
|
||||||
@ -80,10 +87,67 @@ class SettingsWidget(SettingsUI):
|
|||||||
if hasattr(self, 'back_button'):
|
if hasattr(self, 'back_button'):
|
||||||
self.back_button.clicked.connect(self.back_to_main)
|
self.back_button.clicked.connect(self.back_to_main)
|
||||||
|
|
||||||
|
def load_db_config(self):
|
||||||
|
"""加载数据库配置"""
|
||||||
|
try:
|
||||||
|
# 获取默认数据源
|
||||||
|
default_source = self.config_loader.get_value('database.default', 'sqlite').lower()
|
||||||
|
|
||||||
|
# 设置当前使用的数据源组合框
|
||||||
|
self._update_source_combo_items() # 更新组合框项目
|
||||||
|
|
||||||
|
index = self.current_source_combo.findText(default_source.capitalize(), Qt.MatchFixedString)
|
||||||
|
if index >= 0:
|
||||||
|
self.current_source_combo.setCurrentIndex(index)
|
||||||
|
|
||||||
|
# 默认选择当前使用的数据源类型
|
||||||
|
index = self.db_type_combo.findText(default_source.capitalize(), Qt.MatchFixedString)
|
||||||
|
if index >= 0:
|
||||||
|
self.db_type_combo.setCurrentIndex(index)
|
||||||
|
|
||||||
|
# 更新UI状态
|
||||||
|
self.update_db_ui_state()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"加载数据库配置失败: {e}")
|
||||||
|
|
||||||
|
def _update_source_combo_items(self):
|
||||||
|
"""更新数据源下拉框项目"""
|
||||||
|
try:
|
||||||
|
# 清空当前项目
|
||||||
|
self.current_source_combo.clear()
|
||||||
|
|
||||||
|
# 获取所有配置的数据源
|
||||||
|
sources = self.config_loader.get_value('database.sources', {})
|
||||||
|
|
||||||
|
# 添加数据源到下拉框
|
||||||
|
for source_name in sources.keys():
|
||||||
|
# 处理特殊情况:postgresql显示为PostgreSQL
|
||||||
|
display_name = source_name.capitalize()
|
||||||
|
self.current_source_combo.addItem(display_name, source_name)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"更新数据源下拉框失败: {e}")
|
||||||
|
# 添加默认项
|
||||||
|
self.current_source_combo.addItem("SQLite", "sqlite")
|
||||||
|
|
||||||
def update_db_ui_state(self):
|
def update_db_ui_state(self):
|
||||||
"""根据选择的数据库类型更新UI状态"""
|
"""根据选择的数据库类型更新UI状态"""
|
||||||
if self.sqlite_radio.isChecked():
|
db_type = self.db_type_combo.currentText().lower()
|
||||||
# SQLite模式下,只需要数据库文件路径
|
|
||||||
|
# 处理特殊情况:PostgreSQL对应postgresql
|
||||||
|
if db_type == "postgresql":
|
||||||
|
db_type = "postgresql"
|
||||||
|
|
||||||
|
# 加载选定类型的数据源配置
|
||||||
|
config_path = f"database.sources.{db_type}"
|
||||||
|
db_config = {}
|
||||||
|
|
||||||
|
if db_type == "sqlite":
|
||||||
|
# SQLite模式下,只需要数据库文件路径和说明
|
||||||
|
path = self.config_loader.get_value(f"{config_path}.path", "db/jtDB.db")
|
||||||
|
description = self.config_loader.get_value(f"{config_path}.description", "")
|
||||||
|
|
||||||
self.host_input.setEnabled(False)
|
self.host_input.setEnabled(False)
|
||||||
self.host_input.setText("")
|
self.host_input.setText("")
|
||||||
self.user_input.setEnabled(False)
|
self.user_input.setEnabled(False)
|
||||||
@ -93,41 +157,60 @@ class SettingsWidget(SettingsUI):
|
|||||||
self.port_input.setEnabled(False)
|
self.port_input.setEnabled(False)
|
||||||
self.port_input.setText("")
|
self.port_input.setText("")
|
||||||
self.database_input.setEnabled(True)
|
self.database_input.setEnabled(True)
|
||||||
self.database_input.setText("db/jtDB.db")
|
self.database_input.setText(path)
|
||||||
elif self.pgsql_radio.isChecked():
|
self.desc_input.setText(description)
|
||||||
|
|
||||||
|
elif db_type == "postgresql":
|
||||||
# PostgreSQL模式下,需要完整的连接信息
|
# PostgreSQL模式下,需要完整的连接信息
|
||||||
|
host = self.config_loader.get_value(f"{config_path}.host", "localhost")
|
||||||
|
port = self.config_loader.get_value(f"{config_path}.port", "5432")
|
||||||
|
user = self.config_loader.get_value(f"{config_path}.user", "postgres")
|
||||||
|
password = self.config_loader.get_value(f"{config_path}.password", "")
|
||||||
|
name = self.config_loader.get_value(f"{config_path}.name", "jtDB")
|
||||||
|
description = self.config_loader.get_value(f"{config_path}.description", "")
|
||||||
|
|
||||||
self.host_input.setEnabled(True)
|
self.host_input.setEnabled(True)
|
||||||
self.host_input.setText("localhost")
|
self.host_input.setText(host)
|
||||||
self.user_input.setEnabled(True)
|
self.user_input.setEnabled(True)
|
||||||
self.user_input.setText("postgres")
|
self.user_input.setText(user)
|
||||||
self.password_input.setEnabled(True)
|
self.password_input.setEnabled(True)
|
||||||
self.password_input.setText("")
|
self.password_input.setText(password)
|
||||||
self.port_input.setEnabled(True)
|
self.port_input.setEnabled(True)
|
||||||
self.port_input.setText("5432")
|
self.port_input.setText(port)
|
||||||
self.database_input.setEnabled(True)
|
self.database_input.setEnabled(True)
|
||||||
self.database_input.setText("jtDB")
|
self.database_input.setText(name)
|
||||||
elif self.mysql_radio.isChecked():
|
self.desc_input.setText(description)
|
||||||
|
|
||||||
|
elif db_type == "mysql":
|
||||||
# MySQL模式下,需要完整的连接信息
|
# MySQL模式下,需要完整的连接信息
|
||||||
|
host = self.config_loader.get_value(f"{config_path}.host", "localhost")
|
||||||
|
port = self.config_loader.get_value(f"{config_path}.port", "3306")
|
||||||
|
user = self.config_loader.get_value(f"{config_path}.user", "root")
|
||||||
|
password = self.config_loader.get_value(f"{config_path}.password", "")
|
||||||
|
name = self.config_loader.get_value(f"{config_path}.name", "jtDB")
|
||||||
|
description = self.config_loader.get_value(f"{config_path}.description", "")
|
||||||
|
|
||||||
self.host_input.setEnabled(True)
|
self.host_input.setEnabled(True)
|
||||||
self.host_input.setText("localhost")
|
self.host_input.setText(host)
|
||||||
self.user_input.setEnabled(True)
|
self.user_input.setEnabled(True)
|
||||||
self.user_input.setText("root")
|
self.user_input.setText(user)
|
||||||
self.password_input.setEnabled(True)
|
self.password_input.setEnabled(True)
|
||||||
self.password_input.setText("")
|
self.password_input.setText(password)
|
||||||
self.port_input.setEnabled(True)
|
self.port_input.setEnabled(True)
|
||||||
self.port_input.setText("3306")
|
self.port_input.setText(port)
|
||||||
self.database_input.setEnabled(True)
|
self.database_input.setEnabled(True)
|
||||||
self.database_input.setText("jtDB")
|
self.database_input.setText(name)
|
||||||
|
self.desc_input.setText(description)
|
||||||
|
|
||||||
|
def update_default_source(self):
|
||||||
|
"""更新默认使用的数据源"""
|
||||||
|
default_source = self.current_source_combo.currentText().lower()
|
||||||
|
self.config_loader.set_value('database.default', default_source)
|
||||||
|
logging.info(f"已更新默认使用的数据源为: {default_source}")
|
||||||
|
|
||||||
def get_db_type(self):
|
def get_db_type(self):
|
||||||
"""获取当前选择的数据库类型"""
|
"""获取当前选择的数据库类型"""
|
||||||
if self.sqlite_radio.isChecked():
|
return self.db_type_combo.currentText().lower()
|
||||||
return "sqlite"
|
|
||||||
elif self.pgsql_radio.isChecked():
|
|
||||||
return "pgsql"
|
|
||||||
elif self.mysql_radio.isChecked():
|
|
||||||
return "mysql"
|
|
||||||
return "sqlite" # 默认返回sqlite
|
|
||||||
|
|
||||||
def get_connection_params(self):
|
def get_connection_params(self):
|
||||||
"""获取数据库连接参数"""
|
"""获取数据库连接参数"""
|
||||||
@ -174,19 +257,42 @@ class SettingsWidget(SettingsUI):
|
|||||||
params = self.get_connection_params()[1]
|
params = self.get_connection_params()[1]
|
||||||
desc = self.desc_input.text().strip()
|
desc = self.desc_input.text().strip()
|
||||||
|
|
||||||
# 这里应该将设置保存到配置文件中
|
try:
|
||||||
# 为了简单起见,这里只显示一个消息框
|
# 构建要保存的配置数据
|
||||||
settings_info = f"数据库类型: {db_type}\n"
|
config_path = f"database.sources.{db_type}"
|
||||||
for key, value in params.items():
|
|
||||||
if key != "password":
|
if db_type == "sqlite":
|
||||||
settings_info += f"{key}: {value}\n"
|
self.config_loader.set_value(f"{config_path}.path", params["database"])
|
||||||
|
self.config_loader.set_value(f"{config_path}.description", desc)
|
||||||
else:
|
else:
|
||||||
settings_info += f"{key}: {'*' * len(value)}\n"
|
self.config_loader.set_value(f"{config_path}.host", params["host"])
|
||||||
|
self.config_loader.set_value(f"{config_path}.port", params["port"])
|
||||||
settings_info += f"说明: {desc}"
|
self.config_loader.set_value(f"{config_path}.user", params["user"])
|
||||||
|
self.config_loader.set_value(f"{config_path}.password", params["password"])
|
||||||
QMessageBox.information(self, "设置已保存", f"数据库设置已保存!\n\n{settings_info}")
|
self.config_loader.set_value(f"{config_path}.name", params["database"])
|
||||||
logging.info(f"数据库设置已保存,类型: {db_type}")
|
self.config_loader.set_value(f"{config_path}.description", desc)
|
||||||
|
|
||||||
|
# 更新数据源下拉框
|
||||||
|
self._update_source_combo_items()
|
||||||
|
|
||||||
|
# 构建要显示的消息
|
||||||
|
settings_info = f"数据库类型: {db_type}\n"
|
||||||
|
for key, value in params.items():
|
||||||
|
if key != "password":
|
||||||
|
settings_info += f"{key}: {value}\n"
|
||||||
|
else:
|
||||||
|
settings_info += f"{key}: {'*' * len(value)}\n"
|
||||||
|
|
||||||
|
settings_info += f"说明: {desc}"
|
||||||
|
|
||||||
|
# 显示成功消息
|
||||||
|
QMessageBox.information(self, "设置已保存", f"数据库设置已保存!\n\n{settings_info}")
|
||||||
|
logging.info(f"数据库设置已保存,类型: {db_type}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# 显示错误消息
|
||||||
|
QMessageBox.critical(self, "保存失败", f"保存数据库设置失败!\n\n错误: {str(e)}")
|
||||||
|
logging.error(f"保存数据库设置失败: {str(e)}")
|
||||||
|
|
||||||
def handle_inspection_configs_changed(self):
|
def handle_inspection_configs_changed(self):
|
||||||
"""处理检验配置变更"""
|
"""处理检验配置变更"""
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user