feat: 如果开启 api 接口,那么就推送数据
This commit is contained in:
parent
c091a55cb0
commit
0906f188fb
83
apis/gc_api.py
Normal file
83
apis/gc_api.py
Normal file
@ -0,0 +1,83 @@
|
||||
from utils.api_utils import ApiUtils
|
||||
import logging
|
||||
import json
|
||||
class GcApi:
|
||||
def __init__(self):
|
||||
"""初始化托盘API工具类"""
|
||||
self.api_utils = ApiUtils()
|
||||
|
||||
def get_gc_info(self, gc_code):
|
||||
"""
|
||||
获取GC信息
|
||||
|
||||
Args:
|
||||
gc_code: GC编号
|
||||
|
||||
Returns:
|
||||
dict: GC信息
|
||||
"""
|
||||
try:
|
||||
# API 配置中的键名
|
||||
api_key = "get_gc_info"
|
||||
# 构建 form-data 格式的数据
|
||||
data = {
|
||||
"sc_gch": gc_code,
|
||||
"data_corp":"JT"
|
||||
}
|
||||
# 将工程号作为参数传递,使用 data 参数传递 form-data 格式数据
|
||||
response = self.api_utils.post(api_key, data=data)
|
||||
|
||||
# 请求失败时返回空数据
|
||||
if not response.get("status", False):
|
||||
return {
|
||||
"success": False,
|
||||
"message": "获取GC信息失败",
|
||||
"data": None
|
||||
}
|
||||
return response
|
||||
except Exception as e:
|
||||
logging.error(f"获取GC信息失败: {str(e)}")
|
||||
return None
|
||||
def get_order_info(self, order_code):
|
||||
"""
|
||||
获取订单信息
|
||||
"""
|
||||
try:
|
||||
# API 配置中的键名
|
||||
api_key = "get_order_info"
|
||||
# 构建 form-data 格式的数据
|
||||
order_dict = {"srch_mo":order_code,"data_corp":"JT"}
|
||||
data = {
|
||||
"parms": json.dumps(order_dict), # 必须将数据序列化为JSON字符串
|
||||
"pageIndex": 0,
|
||||
"pageSize": 10,
|
||||
"sortField": "",
|
||||
"sortOrder": ""
|
||||
}
|
||||
# 将工程号作为参数传递,使用 data 参数传递 form-data 格式数据
|
||||
response = self.api_utils.post(api_key, data=data)
|
||||
return response
|
||||
except Exception as e:
|
||||
logging.error(f"获取订单信息失败: {str(e)}")
|
||||
return None
|
||||
def add_order_info(self, info):
|
||||
"""
|
||||
添加订单信息
|
||||
"""
|
||||
try:
|
||||
# API 配置中的键名
|
||||
api_key = "add_order_info"
|
||||
# 构建 form-data 格式的数据
|
||||
data = {
|
||||
"parms": json.dumps(info), # 必须将数据序列化为JSON字符串
|
||||
"pageIndex": 0,
|
||||
"pageSize": 10,
|
||||
"sortField": "",
|
||||
"sortOrder": ""
|
||||
}
|
||||
# 将工程号作为参数传递,使用 data 参数传递 form-data 格式数据
|
||||
response = self.api_utils.post(api_key, data=data)
|
||||
return response
|
||||
except Exception as e:
|
||||
logging.error(f"添加订单信息失败: {str(e)}")
|
||||
return None
|
||||
@ -8,10 +8,13 @@
|
||||
"enable_camera": false
|
||||
},
|
||||
"base_url": "http://localhost:8084",
|
||||
"mode": "standalone"
|
||||
"mode": "api"
|
||||
},
|
||||
"apis": {
|
||||
"get_tray_info": "/apjt/xcsc/tpda/getByTp_note/"
|
||||
"get_tray_info": "/apjt/xcsc/tpda/getByTp_note/",
|
||||
"get_gc_info": "/jsjt/xcsc/tprk/getBZGCInfoToWsbz.do",
|
||||
"get_order_info": "/jsjt/xcsc/tprk/getXsddBzrkGridListToWsbz.do",
|
||||
"add_order_info": "/jsjt/xcsc/tprk/bzrkAdd01.do"
|
||||
},
|
||||
"database": {
|
||||
"default": "sqlite",
|
||||
|
||||
29
dao/gc_dao.py
Normal file
29
dao/gc_dao.py
Normal file
@ -0,0 +1,29 @@
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from utils.sql_utils import SQLUtils
|
||||
|
||||
class GcDao:
|
||||
"""检验项目配置和数据访问对象"""
|
||||
|
||||
def __init__(self):
|
||||
"""初始化数据访问对象"""
|
||||
self.db = SQLUtils('sqlite', database='db/jtDB.db')
|
||||
|
||||
def __del__(self):
|
||||
"""析构函数,确保数据库连接关闭"""
|
||||
if hasattr(self, 'db'):
|
||||
self.db.close()
|
||||
|
||||
def get_gc_info_by_id(self, id):
|
||||
"""根据id获取GC信息"""
|
||||
try:
|
||||
sql = """
|
||||
SELECT * FROM wsbz_gc_info WHERE id = ?
|
||||
"""
|
||||
self.db.cursor.execute(sql, (id,))
|
||||
return self.db.cursor.fetchone()
|
||||
except Exception as e:
|
||||
logging.error(f"获取GC信息失败: {str(e)}")
|
||||
return None
|
||||
|
||||
@ -214,7 +214,72 @@ class InspectionDAO:
|
||||
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
|
||||
|
||||
sql = """
|
||||
INSERT INTO wsbz_order_info (
|
||||
data_corp, user_id, user_name, gzl_zl, ddmo, xpack,
|
||||
sc_gch, qd, spack_type, mxzs, jt, ddnote, code, type,
|
||||
lable, lib, gzl, maxsl, cz, size, cd, luno, qfqd,
|
||||
pono, xj, ysl, dycz, zh, edit_id, remarks
|
||||
) VALUES (
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||
)
|
||||
"""
|
||||
|
||||
params = (
|
||||
data.get("data_corp", "JT"),
|
||||
data.get("user_id", ""),
|
||||
data.get("user_name", ""),
|
||||
data.get("zx_zl", ""),
|
||||
data.get("note", ""),
|
||||
data.get("xpack", ""),
|
||||
order_id if order_id else "",
|
||||
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("zh", ""),
|
||||
data.get("edit_id", ""),
|
||||
data.get("remarks", ""),
|
||||
)
|
||||
|
||||
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, data, username='system'):
|
||||
"""保存检验数据
|
||||
|
||||
@ -314,7 +379,7 @@ class InspectionDAO:
|
||||
LEFT JOIN wsbz_inspection_config c ON d.config_id = c.id
|
||||
WHERE d.is_deleted = FALSE AND d.tray_id = ?
|
||||
AND d.order_id IN ({placeholders})
|
||||
ORDER BY d.create_time, d.order_id, d.position
|
||||
ORDER BY d.create_time
|
||||
"""
|
||||
|
||||
params = [tray_id] + order_ids
|
||||
@ -384,8 +449,7 @@ class InspectionDAO:
|
||||
return data_list
|
||||
except Exception as e:
|
||||
logging.error(f"获取检验数据失败: {str(e)}")
|
||||
return []
|
||||
|
||||
return []
|
||||
|
||||
def get_package_record(self, tray_id):
|
||||
"""根据托盘号获取包装记录
|
||||
@ -458,4 +522,182 @@ class InspectionDAO:
|
||||
self.db.conn.commit()
|
||||
except Exception as e:
|
||||
logging.error(f"删除检验数据失败: {str(e)}")
|
||||
self.db.conn.rollback()
|
||||
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 else 0
|
||||
except Exception as e:
|
||||
logging.error(f"获取轴号失败: {str(e)}")
|
||||
return 0
|
||||
def get_axios_num(self, tray_id):
|
||||
"""获取托盘号对应的轴号"""
|
||||
try:
|
||||
sql = """
|
||||
SELECT max(axis_package_id) 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 sc_gch = ?
|
||||
"""
|
||||
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_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 order_id, MIN(create_time) as first_create_time
|
||||
FROM wsbz_inspection_data
|
||||
WHERE order_id IN ({placeholders}) AND is_deleted = FALSE
|
||||
GROUP BY order_id
|
||||
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 data_corp,user_id,user_name,gzl_zl,mzl,ddmo,xpack,sc_gch,qd,spack_type,mxzs,jt,ddnote,code,
|
||||
type,lable,lib,gzl,maxsl,cz,size,cd,luno,qfqd,pono,xj,ysl,dycz,zh,edit_id,remarks
|
||||
FROM wsbz_order_info WHERE sc_gch = ?
|
||||
"""
|
||||
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, 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 order_id = ?
|
||||
AND tray_id = ?
|
||||
AND CASE WHEN t1.position = 12 THEN 'mzl' ELSE name END IS NOT NULL
|
||||
AND COALESCE(value, '') != ''
|
||||
"""
|
||||
params = (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 {}
|
||||
BIN
db/jtDB.db
BIN
db/jtDB.db
Binary file not shown.
@ -2,14 +2,16 @@ from pymodbus.client import ModbusTcpClient
|
||||
|
||||
client = ModbusTcpClient('localhost', port=5020)
|
||||
client.connect()
|
||||
# client.write_registers(address=11, values=[114])
|
||||
# client.write_registers(address=11, values=[110])
|
||||
client.write_registers(address=13, values=[1])
|
||||
|
||||
# client.write_registers(address=6, values=[1])
|
||||
# client.write_registers(address=5, values=[16])
|
||||
# 贴标完成
|
||||
# client.write_registers(address=13, values=[1])
|
||||
# client.write_registers(address=24, values=[1])
|
||||
# client.write_registers(address=13, values=[0])
|
||||
|
||||
|
||||
result = client.read_holding_registers(address=4, count=1)
|
||||
result = client.read_holding_registers(address=13, count=1)
|
||||
print(result.registers[0],"123===")
|
||||
client.close()
|
||||
48
tests/test_gc_api.py
Normal file
48
tests/test_gc_api.py
Normal file
@ -0,0 +1,48 @@
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
# 添加项目根目录到系统路径,以便导入模块
|
||||
project_root = str(Path(__file__).parent.parent)
|
||||
sys.path.insert(0, project_root)
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(name)s - [%(funcName)s:%(lineno)d] - %(message)s')
|
||||
|
||||
# 导入需要测试的模块
|
||||
from apis.gc_api import GcApi
|
||||
|
||||
def test_gc_api():
|
||||
"""测试 GcApi 的 get_gc_info 方法是否能正确处理 form-data 格式的请求"""
|
||||
print("开始测试 GcApi.get_gc_info 方法...")
|
||||
|
||||
# 创建 GcApi 实例
|
||||
gc_api = GcApi()
|
||||
|
||||
# 测试工程号
|
||||
test_gc_code = "JTPD25060003"
|
||||
|
||||
# 调用方法
|
||||
print(f"使用工程号 {test_gc_code} 调用 get_gc_info...")
|
||||
response = gc_api.get_gc_info(test_gc_code)
|
||||
|
||||
# 打印结果
|
||||
print(f"API 响应: {response}")
|
||||
|
||||
if response:
|
||||
print("测试成功: API 返回了有效响应")
|
||||
else:
|
||||
print("测试失败: API 返回了空响应")
|
||||
|
||||
# 检查响应格式
|
||||
if isinstance(response, dict) and "status" in response:
|
||||
print(f"响应状态: {response.get('status', False)}")
|
||||
print(f"响应消息: {response.get('message', '')}")
|
||||
print(f"响应数据: {response.get('data', None)}")
|
||||
else:
|
||||
print(f"响应格式不符合预期: {response}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_gc_api()
|
||||
@ -1,6 +1,7 @@
|
||||
import requests
|
||||
import json
|
||||
from .config_loader import ConfigLoader
|
||||
import logging
|
||||
|
||||
class ApiUtils:
|
||||
def __init__(self):
|
||||
@ -54,10 +55,22 @@ class ApiUtils:
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
# 如果是 POST 请求且有表单数据,则使用 form-data 格式
|
||||
if method.upper() == "POST" and data and not json_data:
|
||||
# 对于 form-data 格式,不设置 Content-Type,让 requests 自动处理
|
||||
default_headers = {}
|
||||
|
||||
if headers:
|
||||
default_headers.update(headers)
|
||||
|
||||
try:
|
||||
# 记录请求信息,便于调试
|
||||
logging.info(f"发送 {method} 请求到 {full_url}")
|
||||
logging.info(f"参数: {params}")
|
||||
logging.info(f"数据: {data}")
|
||||
logging.info(f"JSON数据: {json_data}")
|
||||
logging.info(f"请求头: {default_headers}")
|
||||
|
||||
response = requests.request(
|
||||
method=method,
|
||||
url=full_url,
|
||||
@ -67,11 +80,17 @@ class ApiUtils:
|
||||
headers=default_headers
|
||||
)
|
||||
|
||||
# 记录响应状态
|
||||
logging.info(f"响应状态码: {response.status_code}")
|
||||
logging.info(f"响应内容: {response.text[:500]}...") # 只记录前500个字符
|
||||
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except requests.exceptions.RequestException as e:
|
||||
logging.error(f"请求异常: {str(e)}")
|
||||
return {"success": False, "message": f"请求异常: {str(e)}"}
|
||||
except json.JSONDecodeError:
|
||||
except json.JSONDecodeError as e:
|
||||
logging.error(f"响应数据不是有效的JSON格式: {str(e)}")
|
||||
return {"success": False, "message": "响应数据不是有效的 JSON 格式"}
|
||||
|
||||
def get(self, url, params=None, headers=None):
|
||||
|
||||
@ -76,17 +76,32 @@ class LoadingDialog(LoadingDialogUI):
|
||||
# 如果返回的是元组(数据库查询结果),将其转换为字典
|
||||
# 根据dao/pallet_type_dao.py中get_pallet_info_by_pallet_id方法的SQL查询
|
||||
# 返回的字段顺序为:pallet_code, pallet_name, description, axios_name, axios_type, tier, size, amount, weight
|
||||
response = {
|
||||
"success": True,
|
||||
"data": {
|
||||
"tp_note": pallet_info[0] if len(pallet_info) > 0 else "",
|
||||
"product_name": pallet_info[1] if len(pallet_info) > 1 else "",
|
||||
"axis_type": pallet_info[4] if len(pallet_info) > 4 else "",
|
||||
"tier": str(pallet_info[5]) if len(pallet_info) > 5 else "",
|
||||
"weight": str(pallet_info[8]) if len(pallet_info) > 8 else "",
|
||||
"quantity": ""
|
||||
try:
|
||||
response = {
|
||||
"success": True,
|
||||
"data": {
|
||||
"tp_note": pallet_info[0] if isinstance(pallet_info, tuple) and len(pallet_info) > 0 else "",
|
||||
"product_name": pallet_info[1] if isinstance(pallet_info, tuple) and len(pallet_info) > 1 else "",
|
||||
"axis_type": pallet_info[4] if isinstance(pallet_info, tuple) and len(pallet_info) > 4 else "",
|
||||
"tier": str(pallet_info[5]) if isinstance(pallet_info, tuple) and len(pallet_info) > 5 else "",
|
||||
"weight": str(pallet_info[8]) if isinstance(pallet_info, tuple) and len(pallet_info) > 8 else "",
|
||||
"quantity": ""
|
||||
}
|
||||
}
|
||||
except (IndexError, TypeError) as e:
|
||||
logging.warning(f"处理托盘信息时出错: {str(e)}, pallet_info类型: {type(pallet_info)}")
|
||||
# 如果pallet_info是字符串或其他非元组类型,创建一个基本响应
|
||||
response = {
|
||||
"success": True,
|
||||
"data": {
|
||||
"tp_note": tray_code,
|
||||
"product_name": "",
|
||||
"axis_type": "",
|
||||
"tier": "",
|
||||
"weight": "",
|
||||
"quantity": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
logging.info(f"托盘信息响应: {response}")
|
||||
|
||||
@ -25,7 +25,7 @@ def get_user_info(user_id):
|
||||
try:
|
||||
# 始终使用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, corp_id as corp_name, corp_id FROM wsbz_user WHERE username = ?", (user_id,))
|
||||
result = db.fetchone()
|
||||
db.close()
|
||||
if result:
|
||||
@ -70,7 +70,7 @@ class LoginWidget(LoginUI):
|
||||
return
|
||||
if check_user_login(user_id, password):
|
||||
try:
|
||||
user_name, corp_name, corp_id, position_id = get_user_info(user_id)
|
||||
user_name, corp_name, corp_id = get_user_info(user_id)
|
||||
if not corp_name:
|
||||
corp_name = "未知公司"
|
||||
# 移除登录成功的弹框
|
||||
@ -81,7 +81,7 @@ class LoginWidget(LoginUI):
|
||||
try:
|
||||
import logging
|
||||
logging.info(f"正在创建主窗口,用户ID: {user_id}, 姓名: {user_name}, 公司: {corp_name}")
|
||||
self.main_window = MainWindow(user_id, user_name, corp_name, corp_id, position_id)
|
||||
self.main_window = MainWindow(user_id, user_name, corp_name, corp_id)
|
||||
self.main_window.showMaximized() # 窗口最大化显示
|
||||
logging.info("主窗口已显示(最大化)")
|
||||
except Exception as e:
|
||||
|
||||
@ -6,6 +6,8 @@ from datetime import datetime
|
||||
from pathlib import Path
|
||||
from utils.modbus_utils import ModbusUtils
|
||||
from utils.modbus_monitor import get_instance as get_modbus_monitor
|
||||
from utils.app_mode import AppMode
|
||||
from apis.gc_api import GcApi
|
||||
from utils.register_handlers import (
|
||||
NGHandler,
|
||||
WeightDataHandler,
|
||||
@ -44,14 +46,13 @@ from utils.serial_manager import SerialManager
|
||||
class MainWindow(MainWindowUI):
|
||||
"""主窗口"""
|
||||
|
||||
def __init__(self, user_id=None, user_name=None, corp_name=None, corp_id=None, position_id=None):
|
||||
def __init__(self, user_id=None, user_name=None, corp_name=None, corp_id=None):
|
||||
super().__init__()
|
||||
|
||||
self.user_id = user_id
|
||||
self.user_name = user_name
|
||||
self.corp_name = corp_name
|
||||
self.corp_id = corp_id
|
||||
self.position_id = position_id
|
||||
self.init_seq = {} # 初始化轴包装的序号
|
||||
self._loading_data_in_progress = False # 数据加载状态标志,防止循环调用
|
||||
|
||||
@ -172,51 +173,18 @@ class MainWindow(MainWindowUI):
|
||||
|
||||
# 加载托盘号列表
|
||||
self.load_pallet_codes()
|
||||
|
||||
# def add_pallet_type_selectors(self):
|
||||
# """添加托盘类型选择下拉框"""
|
||||
# # 创建上料托盘类型选择下拉框
|
||||
# self.input_pallet_type_label = QLabel("上料托盘类型:")
|
||||
# self.input_pallet_type_label.setFont(self.normal_font)
|
||||
# self.input_pallet_type_label.setVisible(False)
|
||||
# self.material_form_layout.addRow(self.input_pallet_type_label)
|
||||
|
||||
# self.input_pallet_type_combo = QComboBox()
|
||||
# self.input_pallet_type_combo.setFont(self.normal_font)
|
||||
# self.input_pallet_type_combo.setVisible(False)
|
||||
# self.material_form_layout.addRow("", self.input_pallet_type_combo)
|
||||
|
||||
# # 创建下料托盘类型选择下拉框
|
||||
# self.output_pallet_type_label = QLabel("下料托盘类型:")
|
||||
# self.output_pallet_type_label.setFont(self.normal_font)
|
||||
# self.output_pallet_type_label.setVisible(False)
|
||||
# self.output_form_layout.addRow(self.output_pallet_type_label)
|
||||
|
||||
# self.output_pallet_type_combo = QComboBox()
|
||||
# self.output_pallet_type_combo.setFont(self.normal_font)
|
||||
# self.output_pallet_type_combo.setVisible(False)
|
||||
# self.output_form_layout.addRow("", self.output_pallet_type_combo)
|
||||
|
||||
# # 加载托盘类型数据
|
||||
# self.update_pallet_types()
|
||||
|
||||
# def update_pallet_types(self):
|
||||
# """更新托盘类型下拉框"""
|
||||
# # 重新加载托盘类型数据
|
||||
# self.pallet_type_manager.reload_pallet_types()
|
||||
|
||||
# # 更新上料托盘类型
|
||||
# input_types = self.pallet_type_manager.get_pallet_types_by_operation("input")
|
||||
# self.input_pallet_type_combo.clear()
|
||||
# for pallet_type in input_types:
|
||||
# self.input_pallet_type_combo.addItem(pallet_type['type_name'], pallet_type['id'])
|
||||
|
||||
# # 更新下料托盘类型
|
||||
# output_types = self.pallet_type_manager.get_pallet_types_by_operation("output")
|
||||
# self.output_pallet_type_combo.clear()
|
||||
# for pallet_type in output_types:
|
||||
# self.output_pallet_type_combo.addItem(pallet_type['type_name'], pallet_type['id'])
|
||||
|
||||
def get_axios_num(self,tray_id):
|
||||
"""获取托盘号对应的轴号"""
|
||||
from dao.inspection_dao import InspectionDAO
|
||||
inspection_dao = InspectionDAO()
|
||||
axios_num = inspection_dao.get_axios_num(tray_id)
|
||||
return axios_num
|
||||
def get_axios_num_by_order_id(self, order_id):
|
||||
"""获取订单号对应的轴号"""
|
||||
from dao.inspection_dao import InspectionDAO
|
||||
inspection_dao = InspectionDAO()
|
||||
axios_num = inspection_dao.get_axios_num_by_order_id(order_id)
|
||||
return axios_num
|
||||
def load_config(self):
|
||||
"""加载配置文件"""
|
||||
config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "config", "app_config.json")
|
||||
@ -308,7 +276,7 @@ class MainWindow(MainWindowUI):
|
||||
logging.info("显示主页面")
|
||||
|
||||
def load_pallet_codes(self):
|
||||
"""从托盘类型管理器加载托盘号并更新到tray_edit"""
|
||||
"""从托盘类型管理器加载托盘号并更新到tray_edit TODO:要实现动态数据源切换"""
|
||||
try:
|
||||
# 获取当前文本,以便保留用户选择
|
||||
current_text = self.tray_edit.currentText()
|
||||
@ -696,12 +664,40 @@ class MainWindow(MainWindowUI):
|
||||
logging.info("工程号输入框按下回车事件")
|
||||
# 获取当前输入的工程号
|
||||
order_text = self.order_edit.text().strip()
|
||||
|
||||
tray_id = self.tray_edit.currentText()
|
||||
if order_text:
|
||||
logging.info(f"输入的工程号: {order_text}")
|
||||
|
||||
# 在微丝产线表格中添加一条新记录
|
||||
self.add_new_inspection_row(order_text)
|
||||
#判断是否是接口,如果不是接口直接添加如果是则走接口
|
||||
# 如果开启接口模式,则需要调用接口同步到业务库
|
||||
order_info = None
|
||||
if AppMode.is_api():
|
||||
# 调用接口
|
||||
gc_api = GcApi()
|
||||
gc_response = gc_api.get_gc_info(order_text)
|
||||
axios_num = self.get_axios_num(tray_id)
|
||||
# 防止response为None导致异常
|
||||
if bool(gc_response.get("status", False)):
|
||||
# 获取工程号信息,并且初始化数据
|
||||
data = gc_response.get("data", {})
|
||||
order_response = gc_api.get_order_info(data.get("ddnote",{}))
|
||||
if(order_response.get("status",False)):
|
||||
# 将接口数据保存到数据库,用于后续的关联使用
|
||||
from dao.inspection_dao import InspectionDAO
|
||||
inspection_dao = InspectionDAO()
|
||||
order_info = order_response.get("data", {})[0]
|
||||
# 设置轴数
|
||||
order_info["axios_num"] = axios_num
|
||||
order_info["sc_gch"] = order_text
|
||||
order_info['user_id'] = self.user_id
|
||||
order_info['user_name'] = self.user_name
|
||||
order_info['data_corp'] = self.corp_id
|
||||
inspection_dao.save_order_info(order_text,order_info)
|
||||
|
||||
|
||||
|
||||
# 在微丝产线表格中添加一条新记录
|
||||
self.add_new_inspection_row(order_text,order_info)
|
||||
|
||||
|
||||
else:
|
||||
logging.warning("工程号为空")
|
||||
@ -710,11 +706,12 @@ class MainWindow(MainWindowUI):
|
||||
# 处理完后可以清除焦点,让输入框失去焦点
|
||||
self.central_widget.setFocus()
|
||||
|
||||
def add_new_inspection_row(self, order_id):
|
||||
def add_new_inspection_row(self, order_id, order_info):
|
||||
"""在微丝产线表格中添加一条新记录,添加到表格末尾
|
||||
|
||||
Args:
|
||||
order_id: 工程号
|
||||
order_info: 从接口获取的工程号信息
|
||||
"""
|
||||
try:
|
||||
# 获取启用的检验配置
|
||||
@ -757,9 +754,36 @@ class MainWindow(MainWindowUI):
|
||||
for i, config in enumerate(enabled_configs):
|
||||
col_index = 2 + i # 检验列从第3列开始
|
||||
|
||||
# 创建空的可编辑单元格
|
||||
# 创建单元格
|
||||
item = QTableWidgetItem("")
|
||||
item.setTextAlignment(Qt.AlignCenter)
|
||||
|
||||
# 如果有order_info数据,尝试匹配字段并设置值
|
||||
if order_info:
|
||||
config_name = config.get('name')
|
||||
# 检查order_info中是否有与config_name匹配的键
|
||||
if config_name in order_info:
|
||||
value = str(order_info[config_name])
|
||||
item = QTableWidgetItem(value)
|
||||
item.setTextAlignment(Qt.AlignCenter)
|
||||
# 设置单元格背景为浅绿色,表示自动填充
|
||||
item.setBackground(QBrush(QColor("#c8e6c9")))
|
||||
|
||||
# 保存到数据库
|
||||
from dao.inspection_dao import InspectionDAO
|
||||
inspection_dao = InspectionDAO()
|
||||
tray_id = self.tray_edit.currentText()
|
||||
data = [{
|
||||
'position': config.get('position'),
|
||||
'config_id': config.get('id'),
|
||||
'value': value,
|
||||
'status': 'pass', # 默认设置为通过状态
|
||||
'remark': '',
|
||||
'tray_id': tray_id
|
||||
}]
|
||||
inspection_dao.save_inspection_data(order_id, data)
|
||||
logging.info(f"自动填充字段 {config_name} 值为 {value}")
|
||||
|
||||
# 设置单元格属性以标识其关联的检验项
|
||||
item.setData(Qt.UserRole, config.get('id'))
|
||||
self.process_table.setItem(data_start_row, col_index, item)
|
||||
@ -790,16 +814,20 @@ class MainWindow(MainWindowUI):
|
||||
tray_id = self.tray_edit.currentText()
|
||||
|
||||
# 为每个检验位置创建一个空记录,确保工程号在数据库中存在
|
||||
# 只为没有自动填充值的配置创建空记录
|
||||
for config in enabled_configs:
|
||||
data = [{
|
||||
'position': config.get('position'),
|
||||
'config_id': config.get('id'),
|
||||
'value': '',
|
||||
'status': '', # 默认设置为通过状态
|
||||
'remark': '',
|
||||
'tray_id': tray_id
|
||||
}]
|
||||
inspection_dao.save_inspection_data(order_id, data)
|
||||
config_name = config.get('name')
|
||||
# 如果order_info中没有对应的键,或者order_info为None
|
||||
if not order_info or config_name not in order_info:
|
||||
data = [{
|
||||
'position': config.get('position'),
|
||||
'config_id': config.get('id'),
|
||||
'value': '',
|
||||
'status': '', # 默认设置为通过状态
|
||||
'remark': '',
|
||||
'tray_id': tray_id
|
||||
}]
|
||||
inspection_dao.save_inspection_data(order_id, data)
|
||||
|
||||
# 为贴标和称重也创建空记录
|
||||
for position in [11, 12, 13]: # 11是贴标,12是毛重,13是净重
|
||||
@ -1045,9 +1073,6 @@ class MainWindow(MainWindowUI):
|
||||
|
||||
# 保存到数据库
|
||||
inspection_dao.save_inspection_data(order_id, data)
|
||||
# 注意:不要在这里调用数据加载方法,而是依靠信号和槽机制或QTimer安全地触发加载
|
||||
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"保存检验数据失败: {str(e)}")
|
||||
# 显示错误消息
|
||||
@ -1055,14 +1080,26 @@ class MainWindow(MainWindowUI):
|
||||
|
||||
def _safe_load_data(self):
|
||||
"""安全地加载数据,避免循环调用"""
|
||||
# 获取当前托盘号,用于日志记录
|
||||
tray_id = self.tray_edit.currentText()
|
||||
|
||||
if self._loading_data_in_progress:
|
||||
# 如果已经在加载数据,不要再次触发
|
||||
logging.debug("已有数据加载正在进行,忽略此次请求")
|
||||
logging.debug(f"已有数据加载正在进行,忽略此次请求 (托盘号: {tray_id})")
|
||||
return
|
||||
|
||||
try:
|
||||
self._loading_data_in_progress = True
|
||||
self.load_finished_inspection_data()
|
||||
logging.info(f"数据加载完成,托盘号: {tray_id}")
|
||||
except Exception as e:
|
||||
logging.error(f"安全加载数据失败: {str(e)}, 托盘号: {tray_id}")
|
||||
# 即使加载失败,也尝试显示包装记录
|
||||
try:
|
||||
self.show_pack_item()
|
||||
logging.info(f"加载失败后尝试显示包装记录, 托盘号: {tray_id}")
|
||||
except Exception as ex:
|
||||
logging.error(f"加载失败后显示包装记录失败: {str(ex)}, 托盘号: {tray_id}")
|
||||
finally:
|
||||
self._loading_data_in_progress = False
|
||||
|
||||
@ -1121,8 +1158,10 @@ class MainWindow(MainWindowUI):
|
||||
# 添加数据到表格 - 从第3行开始添加数据
|
||||
row_idx = 2
|
||||
|
||||
# 确保按工程号倒序排列,最新的工程号在最前面
|
||||
sorted_order_ids = sorted(orders_data.keys(), reverse=False)
|
||||
# 使用DAO方法按创建时间排序工程号,确保FIFO顺序(最早创建的在最前面)
|
||||
from dao.inspection_dao import InspectionDAO
|
||||
inspection_dao = InspectionDAO()
|
||||
sorted_order_ids = inspection_dao.get_orders_by_create_time(list(orders_data.keys()))
|
||||
|
||||
for order_id in sorted_order_ids:
|
||||
items = orders_data[order_id]
|
||||
@ -1192,10 +1231,24 @@ class MainWindow(MainWindowUI):
|
||||
finally:
|
||||
# 加载包装记录,但要避免循环调用
|
||||
# 设置一个标志,防止 show_pack_item 触发更多的数据加载
|
||||
if not hasattr(self, '_loading_data_in_progress'):
|
||||
# 只有在_safe_load_data调用此方法,且没有明确设置加载状态的情况下才调用
|
||||
has_loading_flag = hasattr(self, '_loading_data_in_progress')
|
||||
is_loading = getattr(self, '_loading_data_in_progress', False)
|
||||
|
||||
# 如果是被_safe_load_data调用(即已经设置了_loading_data_in_progress),则无需额外设置
|
||||
if has_loading_flag and is_loading:
|
||||
# 直接调用show_pack_item,不改变加载状态
|
||||
try:
|
||||
self.show_pack_item()
|
||||
logging.info("在load_finished_inspection_data中调用show_pack_item")
|
||||
except Exception as e:
|
||||
logging.error(f"在load_finished_inspection_data中调用show_pack_item失败: {str(e)}")
|
||||
# 否则,这是直接调用此方法(非_safe_load_data),需要设置加载状态
|
||||
elif not is_loading:
|
||||
self._loading_data_in_progress = True
|
||||
try:
|
||||
self.show_pack_item()
|
||||
logging.info("在load_finished_inspection_data中直接调用show_pack_item")
|
||||
finally:
|
||||
self._loading_data_in_progress = False
|
||||
|
||||
@ -1248,7 +1301,7 @@ class MainWindow(MainWindowUI):
|
||||
inspection_dao.save_package_record(order_id, tray_id, label_value, weight_value,net_weight_value, finish_time)
|
||||
|
||||
# 回显数据,但避免循环调用
|
||||
if not hasattr(self, '_loading_data_in_progress'):
|
||||
if not getattr(self, '_loading_data_in_progress'):
|
||||
self._loading_data_in_progress = True
|
||||
try:
|
||||
self.show_pack_item()
|
||||
@ -1268,17 +1321,37 @@ class MainWindow(MainWindowUI):
|
||||
|
||||
# 获取托盘号
|
||||
tray_id = self.tray_edit.currentText()
|
||||
logging.info(f"显示包装记录,当前托盘号: {tray_id}")
|
||||
|
||||
if not tray_id:
|
||||
logging.warning("托盘号为空,无法显示包装记录")
|
||||
# 清空表格
|
||||
self.record_table.setRowCount(0)
|
||||
self.update_package_statistics()
|
||||
return
|
||||
|
||||
# 读取已包装的记录信息,然后回显到 UI
|
||||
package_record = inspection_dao.get_package_record(tray_id)
|
||||
|
||||
# 记录获取的数据情况
|
||||
if package_record:
|
||||
logging.info(f"成功获取包装记录,托盘号={tray_id},记录数量={len(package_record)}")
|
||||
else:
|
||||
logging.info(f"包装记录为空,托盘号={tray_id}")
|
||||
|
||||
# 完全清空包装记录表格(包括所有行)
|
||||
self.record_table.setRowCount(0)
|
||||
|
||||
# 断开包装记录表的信号连接(如果有)
|
||||
try:
|
||||
self.record_table.cellChanged.disconnect()
|
||||
except:
|
||||
# 检查是否已经连接了cellChanged信号
|
||||
if self.record_table.receivers(self.record_table.cellChanged) > 0:
|
||||
self.record_table.cellChanged.disconnect()
|
||||
except TypeError:
|
||||
# 忽略"Failed to disconnect"类型错误
|
||||
pass
|
||||
except Exception as e:
|
||||
logging.warning(f"断开record_table.cellChanged信号失败: {str(e)}")
|
||||
|
||||
# 设置表头固定不动
|
||||
self.record_table.horizontalHeader().setSectionResizeMode(QHeaderView.Fixed)
|
||||
@ -1373,6 +1446,8 @@ class MainWindow(MainWindowUI):
|
||||
|
||||
# 更新包装记录统计数据
|
||||
self.update_package_statistics()
|
||||
logging.info(f"包装记录显示完成,托盘号={tray_id},总记录数={self.record_table.rowCount()}")
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"显示包装记录失败: {str(e)}")
|
||||
QMessageBox.warning(self, "显示失败", f"显示包装记录失败: {str(e)}")
|
||||
@ -1681,7 +1756,10 @@ class MainWindow(MainWindowUI):
|
||||
self.save_inspection_data(order_id, tray_id, 12, 12, str(weight), "pass")
|
||||
|
||||
# 保存净重到数据库(毛重-工字轮重量,TODO :先默认工字轮重量为10g后续从接口获取)
|
||||
net_weight = weight - 10
|
||||
from dao.inspection_dao import InspectionDAO
|
||||
inspection_dao = InspectionDAO()
|
||||
gzl_zl = inspection_dao.get_gzl_zl(order_id)
|
||||
net_weight = float(weight) - float(gzl_zl)
|
||||
self.save_inspection_data(order_id, tray_id, 13, 13, str(net_weight), "pass")
|
||||
|
||||
# 设置净重单元格
|
||||
@ -1748,8 +1826,8 @@ class MainWindow(MainWindowUI):
|
||||
# 计算贴标列索引 - 贴标位置在检验列之后的第一列
|
||||
label_col = 2 + len(enabled_configs)
|
||||
|
||||
# 生成贴标号(托盘号+序号)
|
||||
label_value = f"{self.init_seq[tray_id]}"
|
||||
# 生成贴标号(托盘号+轴号)
|
||||
axios_num = self.get_axios_num(tray_id)+1
|
||||
|
||||
# 断开单元格变更信号,避免程序自动写入时触发
|
||||
try:
|
||||
@ -1758,15 +1836,15 @@ class MainWindow(MainWindowUI):
|
||||
pass
|
||||
|
||||
# 创建并设置贴标单元格
|
||||
label_item = QTableWidgetItem(label_value)
|
||||
label_item = QTableWidgetItem(axios_num)
|
||||
label_item.setTextAlignment(Qt.AlignCenter)
|
||||
|
||||
# 写入单元格
|
||||
self.process_table.setItem(data_row, label_col, label_item)
|
||||
logging.info(f"已将贴标数据 {label_value} 写入表格单元格 [{data_row}, {label_col}]")
|
||||
logging.info(f"已将贴标数据 {axios_num} 写入表格单元格 [{data_row}, {label_col}]")
|
||||
|
||||
# 保存贴标数据到数据库
|
||||
self.save_inspection_data(order_id, tray_id, 11, 11, label_value, "pass")
|
||||
self.save_inspection_data(order_id, tray_id, 11, 11, axios_num, "pass")
|
||||
|
||||
# 调用加载到包装记录的方法
|
||||
self.load_finished_record_to_package_record(order_id, tray_id)
|
||||
@ -1775,12 +1853,44 @@ class MainWindow(MainWindowUI):
|
||||
# 删除当前处理的行
|
||||
self.process_table.removeRow(data_row)
|
||||
logging.info(f"已删除处理完成的行 {data_row}")
|
||||
|
||||
|
||||
#如果开启 api 模式,则调用接口添加到包装记录
|
||||
if AppMode.is_api():
|
||||
from dao.inspection_dao import InspectionDAO
|
||||
inspection_dao = InspectionDAO()
|
||||
# 调用接口
|
||||
gc_api = GcApi()
|
||||
axios_num = self.get_axios_num_by_order_id(order_id)
|
||||
# 获取订单信息和其他信息,两者都已经是字典格式
|
||||
info = {}
|
||||
order_info = inspection_dao.get_order_info(order_id)
|
||||
info.update(order_info)
|
||||
|
||||
order_others_info = inspection_dao.get_order_others_info(order_id, tray_id)
|
||||
info.update(order_others_info)
|
||||
info['data_corp'] = 'T'
|
||||
info['zh'] = axios_num
|
||||
|
||||
# 获取本机IP地址
|
||||
import socket
|
||||
try:
|
||||
# 通过连接外部服务器获取本机IP(不实际建立连接)
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s.connect(("8.8.8.8", 80))
|
||||
local_ip = s.getsockname()[0]
|
||||
s.close()
|
||||
info['nw_ip'] = local_ip.replace('.', '')
|
||||
except Exception as e:
|
||||
logging.error(f"获取本机IP失败: {str(e)}")
|
||||
# 如果获取失败,使用本地回环地址
|
||||
info['nw_ip'] = '127.0.0.1'.replace('.', '')
|
||||
|
||||
# 调用接口添加到包装记录
|
||||
gc_api.add_order_info(info)
|
||||
|
||||
# 重新连接单元格变更信号
|
||||
self.process_table.cellChanged.connect(self.handle_inspection_cell_changed)
|
||||
|
||||
# 更新托盘号对应的序号
|
||||
self.init_seq[tray_id] += 1
|
||||
except Exception as e:
|
||||
logging.error(f"处理贴标完成信号失败: {str(e)}")
|
||||
# 确保信号重新连接
|
||||
@ -2257,31 +2367,27 @@ class MainWindow(MainWindowUI):
|
||||
tray_id = self.tray_edit.currentText()
|
||||
if tray_id:
|
||||
logging.info(f"托盘号变更为 {tray_id},启动监听")
|
||||
|
||||
# 确保启动Modbus监控
|
||||
if not hasattr(self, 'modbus_monitor') or not self.modbus_monitor.is_running():
|
||||
try:
|
||||
self.setup_modbus_monitor()
|
||||
logging.info("已在托盘号变更时启动Modbus监控")
|
||||
except Exception as e:
|
||||
logging.error(f"托盘号变更时启动Modbus监控失败: {str(e)}")
|
||||
|
||||
# 确保启动串口监听
|
||||
try:
|
||||
self.serial_manager.auto_open_configured_ports()
|
||||
# 启动键盘监听器
|
||||
self.serial_manager.start_keyboard_listener()
|
||||
logging.info("已在托盘号变更时启动串口和键盘监听器")
|
||||
except Exception as e:
|
||||
logging.error(f"托盘号变更时启动串口监听失败: {str(e)}")
|
||||
|
||||
# 初始化托盘号对应的序号(如果不存在)
|
||||
if tray_id not in self.init_seq:
|
||||
self.init_seq[tray_id] = 1
|
||||
logging.info(f"初始化托盘号 {tray_id} 的序号为 1")
|
||||
|
||||
# 加载数据
|
||||
# 加载检验数据
|
||||
self._safe_load_data()
|
||||
|
||||
# 无论_safe_load_data是否成功,都确保显示包装记录
|
||||
# 临时保存当前加载状态
|
||||
prev_loading_state = getattr(self, '_loading_data_in_progress', False)
|
||||
|
||||
try:
|
||||
# 设置加载状态为True,避免无限循环调用
|
||||
self._loading_data_in_progress = True
|
||||
# 强制显示包装记录
|
||||
self.show_pack_item()
|
||||
logging.info(f"托盘号变更:直接调用显示包装记录, 托盘号={tray_id}")
|
||||
finally:
|
||||
# 恢复之前的加载状态
|
||||
self._loading_data_in_progress = prev_loading_state
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"处理托盘号变更失败: {str(e)}")
|
||||
37
widgets/{'note': 'JT2504019', 'type_name': '不锈钢丝.groovy
Normal file
37
widgets/{'note': 'JT2504019', 'type_name': '不锈钢丝.groovy
Normal file
@ -0,0 +1,37 @@
|
||||
{'note': 'JT2504019', 'type_name': '不锈钢丝', 'code': 'CP02013', 'corp': '江苏佳腾', 'spack': 'JT2504019-0005', 'tqd': '780', 'zx_name': 'DIN-355/ABS无字白轴', 'cdname': '待定', 'bzfs': '托盘上大纸箱', 'bccd': '0.494', 'type': 'ZL00', 'bz_bqd': '700', 'maxsl': 35.45, 'ysl': None, 'khjq': '2025-05-31', 'price': 19.2, 'sl': 4600.0, 'spack_type': '木托', 'ddzl': '外销合同', 'qfqd': None, 'customerexp': 'JW', 'zzyq': '42-44', 'cd': '待定', 'mo': 'JT2504019-1', 'dycz': None, 'tccd': '0.506', 'zx_code': 'ZX0023', 'bqlb': '14', 'khno': 'SCJW25-010Add', 'template_name': '日本-白签', 'size': '0.5', 'bqd': None, 'remarks_hb': 'G01|生产注意产品表面及排线,装箱时做好固定,外箱相连两侧各贴一张标签,每箱27轴|42-44公斤/轴,27轴/箱', 'mxid': 17321, 'ddyq': '42-44公斤/轴,27轴/箱', 'cz': '304', 'luno': 'J2410115', 'yzgg': None, 'je': 88320.0, 'zx_zl': '1.95', 'remarks': '42-44公斤/轴,27轴/箱', 'rq': '2025-04-08', 'bz_tqd': '800', 'customer': 'JTDW00070'}
|
||||
size 线径
|
||||
zx_zl 工字轮重量
|
||||
|
||||
{
|
||||
"data_corp":,
|
||||
"user_id":,
|
||||
"user_name":,
|
||||
"gzl_zl":,
|
||||
"mzl":,
|
||||
"ddmo":,
|
||||
"xpack":,
|
||||
"sc_gch":,
|
||||
"qd":,
|
||||
"spack_type":,
|
||||
"mxzs":,
|
||||
"jt":,
|
||||
"ddnote":,
|
||||
"code": ,
|
||||
"type":,
|
||||
"lable":,
|
||||
"lib":,
|
||||
"gzl":,
|
||||
"maxsl":,
|
||||
"cz":,
|
||||
"size":,
|
||||
"cd":,
|
||||
"luno":,
|
||||
"qfqd":,
|
||||
"pono":,
|
||||
"xj":,
|
||||
"ysl":,
|
||||
"dycz":,
|
||||
"zh":,
|
||||
"edit_id":,
|
||||
"remarks":,
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user