import json import logging from datetime import datetime from utils.sql_utils import SQLUtils class InspectionDAO: """检验项目配置和数据访问对象""" def __init__(self): """初始化数据访问对象""" self.db = SQLUtils('sqlite', database='db/jtDB.db') def __del__(self): """析构函数,确保数据库连接关闭""" if hasattr(self, 'db'): self.db.close() def get_all_inspection_configs(self, include_disabled=False): """获取所有检验项目配置 Args: include_disabled: 是否包含禁用的项目 Returns: list: 检验项目配置列表 """ try: if include_disabled: sql = """ SELECT id, position, name, display_name, enabled, required, data_type, min_value, max_value, enum_values, unit, sort_order FROM wsbz_inspection_config WHERE is_deleted = FALSE ORDER BY sort_order, position """ params = () else: sql = """ SELECT id, position, name, display_name, enabled, required, data_type, min_value, max_value, enum_values, unit, sort_order FROM wsbz_inspection_config WHERE is_deleted = FALSE AND enabled = TRUE ORDER BY sort_order, position """ params = () self.db.cursor.execute(sql, params) results = self.db.cursor.fetchall() configs = [] for row in results: config = { 'id': row[0], 'position': row[1], 'name': row[2], 'display_name': row[3], 'enabled': bool(row[4]), 'required': bool(row[5]), 'data_type': row[6], 'min_value': row[7], 'max_value': row[8], 'enum_values': json.loads(row[9]) if row[9] else None, 'unit': row[10], 'sort_order': row[11] } configs.append(config) return configs except Exception as e: logging.error(f"获取检验项目配置失败: {str(e)}") return [] def get_enabled_inspection_configs(self): """获取已启用的检验项目配置 Returns: list: 已启用的检验项目配置列表 """ return self.get_all_inspection_configs(include_disabled=False) def get_inspection_config_by_position(self, position): """根据位置获取检验项目配置 Args: position: 位置序号 (1-6) Returns: dict: 检验项目配置, 未找到则返回None """ try: sql = """ SELECT id, position, name, display_name, enabled, required, data_type, min_value, max_value, enum_values, unit, sort_order FROM wsbz_inspection_config WHERE position = ? AND is_deleted = FALSE """ params = (position,) self.db.cursor.execute(sql, params) row = self.db.cursor.fetchone() if row: config = { 'id': row[0], 'position': row[1], 'name': row[2], 'display_name': row[3], 'enabled': bool(row[4]), 'required': bool(row[5]), 'data_type': row[6], 'min_value': row[7], 'max_value': row[8], 'enum_values': json.loads(row[9]) if row[9] else None, 'unit': row[10], 'sort_order': row[11] } return config else: return None except Exception as e: logging.error(f"获取检验项目配置失败: {str(e)}") return None def update_inspection_config(self, config_id, data, username='system'): """更新检验项目配置 Args: config_id: 配置ID data: 更新数据 username: 操作用户 Returns: bool: 更新是否成功 """ try: current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # 构建更新SQL update_fields = [] params = [] # 可更新的字段 allowed_fields = [ 'name', 'display_name', 'enabled', 'required', 'data_type', 'min_value', 'max_value', 'unit', 'sort_order', 'enum_values' ] for field in allowed_fields: if field in data: # 特殊处理enum_values字段,确保存储为JSON字符串 if field == 'enum_values' and data[field] is not None: if isinstance(data[field], list): update_fields.append(f"{field} = ?") params.append(json.dumps(data[field])) elif isinstance(data[field], str): # 如果已经是字符串,检查是否有效的JSON try: json.loads(data[field]) update_fields.append(f"{field} = ?") params.append(data[field]) except: logging.warning(f"无效的JSON: {data[field]}") continue else: update_fields.append(f"{field} = ?") params.append(data[field]) # 添加更新时间和更新人 update_fields.append("update_time = ?") params.append(current_time) update_fields.append("update_by = ?") params.append(username) # 添加配置ID到参数列表 params.append(config_id) # 构建SQL sql = f""" UPDATE inspection_config SET {', '.join(update_fields)} WHERE id = ? """ self.db.execute_update(sql, params) return True except Exception as e: logging.error(f"更新检验项目配置失败: {str(e)}") return False def toggle_inspection_config(self, position, enabled, username='system'): """启用或禁用检验项目配置 Args: position: 位置序号 (1-6) enabled: 是否启用 username: 操作用户 Returns: bool: 操作是否成功 """ try: current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') sql = """ UPDATE wsbz_inspection_config SET enabled = ?, update_time = ?, update_by = ? WHERE position = ? AND is_deleted = FALSE """ params = (enabled, current_time, username, position) self.db.execute_update(sql, params) return True except Exception as e: logging.error(f"更新检验项目启用状态失败: {str(e)}") return False def save_order_info(self, order_id,data): """保存订单信息到 wsbz_order_info 表 Args: data: 订单信息字典 Returns: bool: 操作是否成功 """ try: if not data: return False # 先检查是否存在记录 check_sql = "SELECT ddmo FROM wsbz_order_info WHERE ddmo = ?" self.db.cursor.execute(check_sql, (data.get("mo", ""),)) existing_record = self.db.cursor.fetchone() if existing_record: # 如果记录存在,执行更新 sql = """ UPDATE wsbz_order_info SET data_corp = ?, user_id = ?, user_name = ?, gzl_zl = ?, xpack = ?, qd = ?, spack_type = ?, mxzs = ?, jt = ?, ddnote = ?, code = ?, type = ?, lable = ?, lib = ?, gzl = ?, maxsl = ?, cz = ?, size = ?, cd = ?, luno = ?, qfqd = ?, pono = ?, xj = ?, ysl = ?, dycz = ?, zx_code = ?, edit_id = ?, remarks = ?, zx_name = ? bccd = ? ,tccd = ? WHERE ddmo = ? """ params = ( data.get("data_corp", "JT"), data.get("user_id", ""), data.get("user_name", ""), data.get("zx_zl", ""), data.get("xpack", ""), data.get("qd", ""), data.get("spack_type", ""), data.get("mxzs", ""), data.get("jt", ""), data.get("note", ""), data.get("code", ""), data.get("type", ""), data.get("template_name", ""), data.get("lib", ""), data.get("zx_code", ""), data.get("maxsl", ""), data.get("cz", ""), data.get("size", ""), data.get("cd", ""), data.get("luno", ""), data.get("qfqd", ""), data.get("khno", ""), data.get("size", ""), data.get("ysl", ""), data.get("dycz", ""), data.get("zx_code", ""), data.get("edit_id", ""), data.get("remarks", ""), data.get("zx_name", ""), data.get("bccd", ""), data.get("tccd", ""), data.get("mo", "") # WHERE 条件参数 ) logging.info(f"更新订单信息: ddmo={data.get('mo', '')}") else: # 如果记录不存在,执行插入 sql = """ INSERT INTO wsbz_order_info ( data_corp, user_id, user_name, gzl_zl, ddmo, xpack, qd, spack_type, mxzs, jt, ddnote, code, type, lable, lib, gzl, maxsl, cz, size, cd, luno, qfqd, pono, xj, ysl, dycz, zx_code, edit_id, remarks,zx_name,bccd,tccd ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) """ params = ( data.get("data_corp", "JT"), data.get("user_id", ""), data.get("user_name", ""), data.get("zx_zl", ""), data.get("mo", ""), data.get("xpack", ""), data.get("qd", ""), data.get("spack_type", ""), data.get("mxzs", ""), data.get("jt", ""), data.get("note", ""), data.get("code", ""), data.get("type", ""), data.get("template_name", ""), data.get("lib", ""), data.get("zx_code", ""), data.get("maxsl", ""), data.get("cz", ""), data.get("size", ""), data.get("cd", ""), data.get("luno", ""), data.get("qfqd", ""), data.get("khno", ""), data.get("size", ""), data.get("ysl", ""), data.get("dycz", ""), data.get("zx_code", ""), data.get("edit_id", ""), data.get("remarks", ""), data.get("zx_name", ""), data.get("bccd", ""), data.get("tccd", "") ) logging.info(f"插入新订单信息: ddmo={data.get('mo', '')}") self.db.cursor.execute(sql, params) self.db.conn.commit() return True except Exception as e: logging.error(f"保存订单信息失败: {str(e)}") self.db.conn.rollback() return False def save_inspection_data(self, order_id,gc_note, data, username='system'): """保存检验数据 Args: order_id: 工程号 data: 检验数据列表,格式: [{'position': 1, 'config_id': 1, 'value': '合格'}, ...] username: 操作用户 Returns: bool: 保存是否成功 """ try: current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') self.db.begin_transaction() for item in data: position = item.get('position') config_id = item.get('config_id') value = item.get('value') status = item.get('status', 'pass') remark = item.get('remark', '') tray_id = item.get('tray_id', '') # 检查是否已存在该工程号和位置的记录 check_sql = """ SELECT id FROM wsbz_inspection_data WHERE order_id = ? and gc_note = ? AND position = ? AND is_deleted = FALSE """ check_params = (order_id,gc_note, position) self.db.cursor.execute(check_sql, check_params) existing = self.db.cursor.fetchone() if existing: # 更新已有记录 update_sql = """ UPDATE wsbz_inspection_data SET config_id = ?, value = ?, status = ?, remark = ?, update_time = ?, update_by = ?, tray_id = ? WHERE id = ? """ update_params = ( config_id, value, status, remark, current_time, username, tray_id, existing[0] ) self.db.cursor.execute(update_sql, update_params) else: # 插入新记录 insert_sql = """ INSERT INTO wsbz_inspection_data ( order_id, position, config_id, value, status, remark, create_time, create_by, is_deleted, tray_id,gc_note ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, FALSE, ?, ?) """ insert_params = ( order_id, position, config_id, value, status, remark, current_time, username, tray_id,gc_note ) self.db.cursor.execute(insert_sql, insert_params) self.db.commit_transaction() return True except Exception as e: self.db.rollback_transaction() logging.error(f"保存检验数据失败: {str(e)}") return False def get_inspection_data_unfinished(self, tray_id): """获取未完成的检验数据,通过是否贴标来判断 Returns: list: 未完成的检验数据列表 """ try: # 先获取所有没有贴标的工程号 sql_orders = """ SELECT DISTINCT d.gc_note FROM wsbz_inspection_data d WHERE d.is_deleted = FALSE AND d.tray_id = ? AND d.position = 11 AND COALESCE(d.value,'') = '' """ params = (tray_id,) self.db.cursor.execute(sql_orders, params) gc_notes = self.db.cursor.fetchall() if not gc_notes: return [] # 构建IN子句的参数 gc_notes = [gc_note[0] for gc_note in gc_notes] placeholders = ','.join(['?' for _ in gc_notes]) # 获取这些工程号的所有检验数据 sql = f""" SELECT d.id, d.gc_note, d.position, d.config_id, d.value, d.status, d.remark, c.name, c.display_name, c.data_type, c.unit FROM wsbz_inspection_data d LEFT JOIN wsbz_inspection_config c ON d.config_id = c.id WHERE d.is_deleted = FALSE AND d.tray_id = ? AND d.gc_note IN ({placeholders}) ORDER BY d.create_time """ params = [tray_id] + gc_notes self.db.cursor.execute(sql, params) results = self.db.cursor.fetchall() data_list = [] for row in results: data = { 'id': row[0], 'gc_note': row[1], 'position': row[2], 'config_id': row[3], 'value': row[4], 'status': row[5], 'remark': row[6], 'name': row[7], 'display_name': row[8], 'data_type': row[9], 'unit': row[10] } data_list.append(data) return data_list except Exception as e: logging.error(f"获取未完成的检验数据失败: {str(e)}") return [] def get_inspection_data_by_order(self, order_id,gc_note, tray_id): """根据工程号获取检验数据 Args: order_id: 订单号 gc_note: 工程号 tray_id: 托盘号 Returns: list: 检验数据列表 """ try: sql = """ SELECT d.id, d.position, d.config_id, d.value, d.status, d.remark, c.name, c.display_name, c.data_type, c.unit FROM wsbz_inspection_data d LEFT JOIN wsbz_inspection_config c ON d.config_id = c.id WHERE d.order_id = ? AND d.gc_note = ? AND d.is_deleted = FALSE AND d.tray_id = ? ORDER BY d.create_time, d.order_id, d.position """ params = (order_id, gc_note, tray_id) self.db.cursor.execute(sql, params) results = self.db.cursor.fetchall() data_list = [] for row in results: data = { 'id': row[0], 'position': row[1], 'config_id': row[2], 'value': row[3], 'status': row[4], 'remark': row[5], 'name': row[6], 'display_name': row[7], 'data_type': row[8], 'unit': row[9] } data_list.append(data) return data_list except Exception as e: logging.error(f"获取检验数据失败: {str(e)}") return [] def get_package_record(self, tray_id): """根据托盘号获取包装记录 Args: tray_id: 托盘号 Returns: list: 包装记录列表 """ try: sql = """ SELECT DISTINCT order_id, gc_note, COALESCE(orders.size, '') as material, COALESCE(orders.cz, '') as spec, tray_id, COALESCE(axis_package_id, '') as axis_package_id, COALESCE(weight, 0) as weight, COALESCE(net_weight, 0) as net_weight, STRFTIME('%Y-%m-%d %H:%M:%S', pack_time) as pack_time FROM wsbz_inspection_pack_data t1 LEFT JOIN wsbz_order_info orders on t1.order_id = orders.ddmo WHERE tray_id = ? AND is_deleted = FALSE ORDER BY pack_time DESC """ params = (tray_id,) self.db.cursor.execute(sql, params) results = self.db.cursor.fetchall() return results except Exception as e: logging.error(f"获取包装记录失败: {str(e)}") return [] def save_package_record(self, order_id, tray_id, label_value, weight_value,net_weight_value, finish_time,gc_note): """保存包装记录 Args: order_id: 工程号 tray_id: 托盘号 label_value: 标签值 weight_value: 重量值 finish_time: 完成时间 """ # TODO:调用接口,获取到工程号对应的其他信息,比如材质,规格,后续完成 try: sql = """ INSERT INTO wsbz_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,gc_note) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?) """ params = (order_id, tray_id, label_value, weight_value, net_weight_value, finish_time, datetime.now(), 'system', datetime.now(), 'system', False,gc_note) self.db.cursor.execute(sql, params) self.db.conn.commit() except Exception as e: logging.error(f"保存包装记录失败: {str(e)}") self.db.conn.rollback() def delete_inspection_data(self, order_id, tray_id): """删除检验数据 Args: order_id: 工程号 tray_id: 托盘号 """ try: sql = """ UPDATE wsbz_inspection_data SET is_deleted = TRUE WHERE order_id = ? AND tray_id = ? """ params = (order_id, tray_id) self.db.cursor.execute(sql, params) self.db.conn.commit() except Exception as e: logging.error(f"删除检验数据失败: {str(e)}") self.db.conn.rollback() def get_axios_num_by_order_id(self, order_id): """获取托盘号对应的轴号""" try: sql = """ SELECT max(axis_package_id) as axios_num FROM wsbz_inspection_pack_data WHERE order_id = ? AND is_deleted = FALSE """ params = (order_id,) self.db.cursor.execute(sql, params) result = self.db.cursor.fetchone() return int(result[0]) if result[0] else 0 except Exception as e: logging.error(f"获取轴号失败: {str(e)}") return 0 def get_axios_num(self, tray_id): """获取托盘号对应的轴号""" try: sql = """ SELECT max(cast(axis_package_id as int)) as axios_num FROM wsbz_inspection_pack_data WHERE tray_id = ? AND is_deleted = FALSE """ params = (tray_id,) self.db.cursor.execute(sql, params) result = self.db.cursor.fetchone() return int(result[0]) if result else 0 except Exception as e: logging.error(f"获取轴号失败: {str(e)}") return 0 def get_gzl_zl(self,order_id): """获取工字轮重量""" try: sql = """ SELECT gzl_zl FROM wsbz_order_info WHERE ddmo = ? """ params = (order_id,) self.db.cursor.execute(sql, params) result = self.db.cursor.fetchone() return result[0] if result else 0 except Exception as e: logging.error(f"获取工字轮重量失败: {str(e)}") return 0 def get_xj_range(self,order_id): """获取线径范围""" try: sql = """ SELECT bccd, tccd FROM wsbz_order_info WHERE ddmo = ? """ params = (order_id,) self.db.cursor.execute(sql, params) result = self.db.cursor.fetchone() return result[0],result[1] if result else None,None except Exception as e: logging.error(f"获取线径范围失败: {str(e)}") return None,None def get_order_create_time(self, order_id): """获取工程号的最早创建时间 Args: order_id: 工程号 Returns: str: 创建时间,格式为'YYYY-MM-DD HH:MM:SS',如果未找到则返回None """ try: sql = """ SELECT MIN(create_time) FROM wsbz_inspection_data WHERE order_id = ? AND is_deleted = FALSE """ self.db.cursor.execute(sql, (order_id,)) result = self.db.cursor.fetchone() return result[0] if result and result[0] else None except Exception as e: logging.error(f"获取工程号创建时间失败: {str(e)}") return None def get_orders_by_create_time(self, order_ids): """按创建时间排序工程号 Args: order_ids: 工程号列表 Returns: list: 按创建时间排序的工程号列表 """ try: if not order_ids: return [] # 构建IN子句 placeholders = ','.join(['?' for _ in order_ids]) # 查询每个工程号的最早创建时间并排序 sql = f""" SELECT gc_note, MIN(create_time) as first_create_time FROM wsbz_inspection_data WHERE gc_note IN ({placeholders}) AND is_deleted = FALSE GROUP BY gc_note ORDER BY first_create_time """ self.db.cursor.execute(sql, order_ids) results = self.db.cursor.fetchall() # 提取排序后的工程号 sorted_order_ids = [row[0] for row in results] # 确保所有传入的工程号都在结果中 for order_id in order_ids: if order_id not in sorted_order_ids: sorted_order_ids.append(order_id) return sorted_order_ids except Exception as e: logging.error(f"按创建时间排序工程号失败: {str(e)}") return order_ids # 出错时返回原始顺序 def get_order_info(self, order_id): """获取订单信息 Args: order_id: 工程号 Returns: dict: 订单信息字典 """ try: sql = """ SELECT distinct data_corp,user_id,user_name,gzl_zl,mzl,ddmo,qd,spack_type,mxzs,jt,ddnote,code, type,lable,lib,gzl,maxsl,cz,size,cd,luno,qfqd,pono,xj,ysl,dycz,edit_id,remarks,zx_name FROM wsbz_order_info WHERE ddmo = ? """ params = (order_id,) self.db.cursor.execute(sql, params) result = self.db.cursor.fetchone() if not result: return {} # 获取列名 column_names = [desc[0] for desc in self.db.cursor.description] # 转换为字典 result_dict = {} for i, value in enumerate(result): if i < len(column_names): result_dict[column_names[i]] = value return result_dict except Exception as e: logging.error(f"获取订单信息失败: {str(e)}") return {} def get_order_others_info(self, gc_note, order_id, tray_id): """获取订单其他信息 Args: order_id: 工程号 tray_id: 托盘号 Returns: dict: 订单其他信息字典,以name为key,value为值 """ try: sql = """ SELECT t1.order_id, CASE WHEN t1.position = 12 THEN 'mzl' ELSE name END AS name, value FROM wsbz_inspection_data t1 LEFT JOIN main.wsbz_inspection_config wic ON t1.config_id = wic.id WHERE gc_note = ? AND t1.order_id = ? AND tray_id = ? AND CASE WHEN t1.position = 12 THEN 'mzl' ELSE name END IS NOT NULL AND COALESCE(value, '') != '' """ params = (gc_note, order_id, tray_id) self.db.cursor.execute(sql, params) results = self.db.cursor.fetchall() if not results: return {} # 将结果转换为字典,以name为key,value为值 result_dict = {} for row in results: if len(row) >= 3: # 确保行至少有3个元素 name = row[1] # name在第二列 value = row[2] # value在第三列 result_dict[name] = value return result_dict except Exception as e: logging.error(f"获取订单其他信息失败: {str(e)}") return {}