#!/usr/bin/env python3 """ 修复状态管理功能的脚本 """ import os import re # 1. 在InspectionDAO类中添加状态管理方法 DAO_METHODS = """ def get_product_status(self, order_id, gc_note, tray_id): \"\"\"获取产品的当前状态 Args: order_id: 订单号 gc_note: 工程号 tray_id: 托盘号 Returns: str: 产品状态,如果没有找到则返回'init' \"\"\" try: with SQLUtils('sqlite', database='db/jtDB.db') as db: sql = \"\"\" SELECT status FROM wsbz_inspection_data WHERE order_id = ? AND gc_note = ? AND tray_id = ? ORDER BY id ASC LIMIT 1 \"\"\" params = (order_id, gc_note, tray_id) result = db.query_one(sql, params) return result[0] if result and result[0] else 'init' # 默认为init状态 except Exception as e: logging.error(f"获取产品状态失败: {str(e)}") return 'init' # 出错时返回默认状态 def update_product_status(self, order_id, gc_note, tray_id, new_status): \"\"\"更新产品的状态 Args: order_id: 订单号 gc_note: 工程号 tray_id: 托盘号 new_status: 新状态 Returns: bool: 更新是否成功 \"\"\" try: with SQLUtils('sqlite', database='db/jtDB.db') as db: # 更新该产品所有记录的状态字段 update_sql = \"\"\" UPDATE wsbz_inspection_data SET status = ?, update_time = ? WHERE order_id = ? AND gc_note = ? AND tray_id = ? \"\"\" update_params = (new_status, datetime.now().strftime('%Y-%m-%d %H:%M:%S'), order_id, gc_note, tray_id) db.execute(update_sql, update_params) logging.info(f"已更新产品状态: 订单号={order_id}, 工程号={gc_note}, 托盘号={tray_id}, 新状态={new_status}") return True except Exception as e: logging.error(f"更新产品状态失败: {str(e)}") return False """ # 2. 检查检验完成的方法 CHECK_INSPECTION_METHOD = """ def check_inspection_completed(self, row): \"\"\"检查行是否有至少一个检验项已完成,如果是则更新状态为inspected Args: row: 行索引 Returns: bool: 是否有至少一个检验项已完成 \"\"\" try: # 获取工程号 gc_note_item = self.process_table.item(row, 1) if not gc_note_item: return False gc_note = gc_note_item.text().strip() tray_id = self.tray_edit.text() # 获取启用的检验配置 enabled_configs = self.inspection_manager.get_enabled_configs() # 检查是否有至少一个检验项有值 has_any_value = False for i, config in enumerate(enabled_configs): col_index = 2 + i item = self.process_table.item(row, col_index) if item and item.text().strip(): has_any_value = True break # 如果有至少一个检验项有值,更新状态为inspected if has_any_value: from dao.inspection_dao import InspectionDAO inspection_dao = InspectionDAO() inspection_dao.update_product_status(self._current_order_code, gc_note, tray_id, 'inspected') logging.info(f"工程号 {gc_note} 的检验已完成,状态更新为inspected") return has_any_value except Exception as e: logging.error(f"检查检验完成状态失败: {str(e)}") return False """ # 3. 修改的save_inspection_data方法 SAVE_INSPECTION_DATA_METHOD = """ def save_inspection_data(self, order_id, gc_note, tray_id, position, config_id, value, status): \"\"\"保存检验数据到数据库 Args: order_id: 订单号 gc_note: 工程号 position: 位置序号 config_id: 配置ID value: 检验值 status: 状态 \"\"\" try: from dao.inspection_dao import InspectionDAO inspection_dao = InspectionDAO() modbus = ModbusUtils() client = modbus.get_client() # 获取当前产品状态,优先使用产品状态管理中的状态 current_status = inspection_dao.get_product_status(order_id, gc_note, tray_id) # 如果当前状态不是初始状态,则使用当前状态而不是传入的status if current_status not in ['', 'init']: status = current_status # 记录保存前的详细日志 logging.info(f"正在保存检验数据: 工程号={gc_note}, 托盘号={tray_id}, 位置={position}, 配置ID={config_id}, 值={value}, 状态={status}") # 构建数据 data = [{ 'position': position, 'config_id': config_id, 'value': value, 'status': status, 'remark': '', 'tray_id': tray_id }] # 保存到数据库 inspection_dao.save_inspection_data(order_id, gc_note, data) """ # 4. 修改_process_stable_weight方法中的查找行逻辑 PROCESS_STABLE_WEIGHT_FIND_ROW = """ # 基于状态查找行:优先查找状态为inspected的行 data_row = None from dao.inspection_dao import InspectionDAO inspection_dao = InspectionDAO() # 首先查找状态为inspected的行 for row in range(2, self.process_table.rowCount()): gc_note_item = self.process_table.item(row, 1) if gc_note_item: row_gc_note = gc_note_item.text().strip() tray_id = self.tray_edit.text() status = inspection_dao.get_product_status(self._current_order_code, row_gc_note, tray_id) if status == 'inspected': data_row = row logging.info(f"找到状态为inspected的行: {data_row}, 工程号: {row_gc_note}") break # 如果没有找到inspected状态的行,回退到原有逻辑 if data_row is None: # 查找第一个没有称重数据的行 for row in range(2, self.process_table.rowCount()): weight_item = self.process_table.item(row, weight_col) if not weight_item or not weight_item.text().strip(): data_row = row break # 如果仍然没有找到,使用当前选中行或第一个数据行 if data_row is None: current_row = self.process_table.currentRow() data_row = current_row if current_row >= 2 else 2 # 使用第一个数据行(索引为2) logging.info(f"未找到状态为inspected的行或没有称重数据的行,使用当前选中行或第一个数据行: {data_row}") else: logging.info(f"找到没有称重数据的行: {data_row}") else: logging.info(f"将使用状态为inspected的行: {data_row}") """ # 5. 添加称重完成后的状态更新代码 PROCESS_STABLE_WEIGHT_UPDATE_STATUS = """ # 更新产品状态为weighed inspection_dao.update_product_status(self._current_order_code, gc_note, tray_id, 'weighed') logging.info(f"工程号 {gc_note} 的称重已完成,状态更新为weighed") """ # 6. 修改handle_label_signal方法中的查找行逻辑 HANDLE_LABEL_SIGNAL_FIND_ROW = """ # 基于状态查找行:优先查找状态为weighed的行 data_row = None from dao.inspection_dao import InspectionDAO inspection_dao = InspectionDAO() # 首先查找状态为weighed的行 for row in range(2, self.process_table.rowCount()): gc_note_item = self.process_table.item(row, 1) if gc_note_item: row_gc_note = gc_note_item.text().strip() tray_id = self.tray_edit.text() status = inspection_dao.get_product_status(self._current_order_code, row_gc_note, tray_id) if status == 'weighed': data_row = row logging.info(f"找到状态为weighed的行: {data_row}, 工程号: {row_gc_note}") break # 如果没有找到weighed状态的行,回退到原有逻辑 if data_row is None: # 使用当前选中的行或第一个数据行 current_row = self.process_table.currentRow() data_row = current_row if current_row >= 2 else 2 # 使用第一个数据行(索引为2) logging.info(f"未找到状态为weighed的行,使用当前选中行或第一个数据行: {data_row}") else: logging.info(f"将使用状态为weighed的行: {data_row}") """ # 7. 添加贴标完成后的状态更新代码 HANDLE_LABEL_SIGNAL_UPDATE_STATUS = """ # 更新产品状态为labeled inspection_dao.update_product_status(self._current_order_code, gc_note, tray_id, 'labeled') logging.info(f"工程号 {gc_note} 的贴标已完成,状态更新为labeled") """ # 8. 在handle_inspection_cell_changed方法末尾添加调用check_inspection_completed HANDLE_INSPECTION_CELL_CHANGED_CALL = """ # 检查是否完成检验并更新状态 self.check_inspection_completed(row) """ # 9. 在add_new_inspection_row方法末尾添加初始化状态代码 ADD_NEW_INSPECTION_ROW_INIT_STATUS = """ # 初始化产品状态为init inspection_dao.update_product_status(self._current_order_code, gc_note, tray_id, 'init') logging.info(f"已添加工程号 {gc_note} 的新记录,显示在第{new_seq}条,初始状态为init") """ # 10. 移除数据校验逻辑,替换为简单的单元格颜色设置 REMOVE_VALIDATION_LOGIC = """ # 设置单元格颜色为浅绿色,表示已填写 cell_item.setBackground(QBrush(QColor("#c8e6c9"))) """ # 主函数:应用所有修改 def apply_fixes(): print("开始应用状态管理功能修复...") # 备份文件 os.system("cp dao/inspection_dao.py dao/inspection_dao.py.bak") os.system("cp widgets/main_window.py widgets/main_window.py.bak") # 1. 添加DAO方法 with open("dao/inspection_dao.py", "r") as f: dao_content = f.read() # 检查方法是否已存在 if "def get_product_status" not in dao_content: # 找到合适的位置插入新方法 pattern = r'def save_package_record.*?return False' match = re.search(pattern, dao_content, re.DOTALL) if match: insert_pos = match.end() new_content = dao_content[:insert_pos] + DAO_METHODS + dao_content[insert_pos:] with open("dao/inspection_dao.py", "w") as f: f.write(new_content) print("1. 已成功添加状态管理方法到 dao/inspection_dao.py") else: print("无法找到合适的位置插入DAO方法") else: print("1. 状态管理方法已存在,跳过添加") # 读取main_window.py with open("widgets/main_window.py", "r") as f: main_window_content = f.read() # 2. 添加check_inspection_completed方法 if "def check_inspection_completed" not in main_window_content: # 找到合适的位置插入新方法 pattern = r'def validate_inspection_value.*?return False' match = re.search(pattern, main_window_content, re.DOTALL) if match: insert_pos = match.end() new_content = main_window_content[:insert_pos] + "\n" + CHECK_INSPECTION_METHOD + main_window_content[insert_pos:] main_window_content = new_content print("2. 已成功添加check_inspection_completed方法") else: print("无法找到合适的位置插入check_inspection_completed方法") else: print("2. check_inspection_completed方法已存在,跳过添加") # 3. 修改save_inspection_data方法 pattern = r'def save_inspection_data.*?inspection_dao\.save_inspection_data\(order_id, gc_note, data\)' replacement = SAVE_INSPECTION_DATA_METHOD main_window_content = re.sub(pattern, replacement, main_window_content, flags=re.DOTALL) print("3. 已成功修改save_inspection_data方法") # 4. 修改_process_stable_weight方法中的查找行逻辑 pattern = r'# 查找第一个没有称重数据的行\s*data_row = None\s*for row in range.*?if data_row is None:.*?else:\s*logging\.info\(f"找到没有称重数据的行: \{data_row\}"\)' replacement = PROCESS_STABLE_WEIGHT_FIND_ROW main_window_content = re.sub(pattern, replacement, main_window_content, flags=re.DOTALL) print("4. 已成功修改_process_stable_weight方法中的查找行逻辑") # 5. 添加称重完成后的状态更新代码 pattern = r'(logging\.info\(f"已将稳定的称重数据 \{weight_kg\}kg 写入行 \{data_row\}, 列 \{weight_col\}"\))\s*\n\s*except' replacement = r'\1\n\n' + PROCESS_STABLE_WEIGHT_UPDATE_STATUS + r'\n except' main_window_content = re.sub(pattern, replacement, main_window_content) print("5. 已成功添加称重完成后的状态更新代码") # 6. 修改handle_label_signal方法中的查找行逻辑 pattern = r'# 获取当前选中的行或第一个数据行\s*current_row = self\.process_table\.currentRow\(\)\s*data_row = current_row if current_row >= 2 else 2' replacement = HANDLE_LABEL_SIGNAL_FIND_ROW main_window_content = re.sub(pattern, replacement, main_window_content) print("6. 已成功修改handle_label_signal方法中的查找行逻辑") # 7. 添加贴标完成后的状态更新代码 pattern = r'(logging\.info\(f"已将贴标数据 \{axios_num\} 保存到数据库"\))\s*\n\s*# 调用加载到包装记录的方法' replacement = r'\1\n\n' + HANDLE_LABEL_SIGNAL_UPDATE_STATUS + r'\n \n # 调用加载到包装记录的方法' main_window_content = re.sub(pattern, replacement, main_window_content) print("7. 已成功添加贴标完成后的状态更新代码") # 8. 在handle_inspection_cell_changed方法末尾添加调用check_inspection_completed pattern = r'(logging\.info\(f"处理单元格变更: 行=\{row\}, 列=\{column\}, 类型=\{data_type\}, 工程号=\{gc_note\}, 值=\{value\}, 状态=\{status\}"\))\s*\n\s*except' replacement = r'\1\n\n' + HANDLE_INSPECTION_CELL_CHANGED_CALL + r'\n except' main_window_content = re.sub(pattern, replacement, main_window_content) print("8. 已成功在handle_inspection_cell_changed方法末尾添加调用check_inspection_completed") # 9. 修改add_new_inspection_row方法,设置初始状态 # 9.1 修改检验项的status为init pattern = r"'status': '',\s*# 默认设置为通过状态" replacement = "'status': 'init', # 设置初始状态" main_window_content = re.sub(pattern, replacement, main_window_content) # 9.2 修改贴标和称重项的status为init pattern = r"'status': 'pass',\s*# 默认设置为通过状态" replacement = "'status': 'init', # 设置初始状态" main_window_content = re.sub(pattern, replacement, main_window_content) # 9.3 添加状态初始化代码 pattern = r'(logging\.info\(f"已添加工程号 \{gc_note\} 的新记录,显示在第\{new_seq\}条"\))\s*\n\s*except' replacement = ADD_NEW_INSPECTION_ROW_INIT_STATUS + r'\n except' main_window_content = re.sub(pattern, replacement, main_window_content) print("9. 已成功修改add_new_inspection_row方法,设置初始状态") # 10. 移除数据校验逻辑 pattern = r'# 验证数据有效性\s*if self\.validate_inspection_value\(config, value\):.*?status = \'warning\'' replacement = REMOVE_VALIDATION_LOGIC main_window_content = re.sub(pattern, replacement, main_window_content, flags=re.DOTALL) print("10. 已成功移除数据校验逻辑") # 保存修改后的main_window.py with open("widgets/main_window.py", "w") as f: f.write(main_window_content) print("状态管理功能修复完成!") if __name__ == "__main__": apply_fixes()