feat(追踪系统): 添加手动设置起始钢卷功能
- 后端添加设置起始钢卷API和钢卷查询API - 前端实现起始钢卷选择界面和状态管理 - 优化追踪逻辑自动加载后续钢卷 - 添加本地存储保持起始钢卷设置
This commit is contained in:
124
backend/main.py
124
backend/main.py
@@ -411,6 +411,22 @@ async def save_opc_config(config: OpcConfig):
|
||||
|
||||
@app.get("/api/opc/status")
|
||||
def opc_status():
|
||||
# 获取当前正在追踪的4个钢卷
|
||||
current_tracking_coils = []
|
||||
try:
|
||||
from sqlite_sync import sqlite_get_coil_track
|
||||
coils = sqlite_get_coil_track()
|
||||
current_tracking_coils = [
|
||||
{
|
||||
"coilid": coil.get("coilid", ""),
|
||||
"sequencenb": coil.get("sequencenb", 0),
|
||||
"rollprogramnb": coil.get("rollprogramnb", 0)
|
||||
}
|
||||
for coil in coils[:4]
|
||||
]
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to get current tracking coils: {e}")
|
||||
|
||||
return {
|
||||
"running": opc_service.running,
|
||||
"last_counter": opc_service.last_counter,
|
||||
@@ -418,6 +434,13 @@ def opc_status():
|
||||
"log": opc_service.event_log[-50:],
|
||||
"track_state": opc_service.track_state,
|
||||
"write_counter_last": opc_service.write_counter_last,
|
||||
"tracking_info": {
|
||||
"first_coilid": opc_service.first_coilid, # 这个保持不变
|
||||
"last_tracked_coilid": opc_service.last_tracked_coilid,
|
||||
"end_coilid": opc_service.end_coilid,
|
||||
"tracking_ended": opc_service.tracking_ended,
|
||||
"current_tracking_coils": current_tracking_coils # 当前正在追踪的4个钢卷
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -664,3 +687,104 @@ async def simulate_signal2():
|
||||
"""模拟信号2触发 - 更新追踪表"""
|
||||
await opc_service._handle_signal2()
|
||||
return {"message": "信号2已触发"}
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────
|
||||
# Manual Starting Coil Configuration
|
||||
# ─────────────────────────────────────────────
|
||||
|
||||
@app.post("/api/track/set-start-coil")
|
||||
async def set_start_coil(data: dict):
|
||||
"""设置手动起始钢卷ID用于追踪"""
|
||||
coilid = data.get("coilid")
|
||||
if not coilid:
|
||||
raise HTTPException(status_code=400, detail="coilid不能为空")
|
||||
|
||||
# 验证钢卷是否存在
|
||||
conn = get_connection()
|
||||
cursor = conn.cursor()
|
||||
try:
|
||||
cursor.execute("SELECT COUNT(*) FROM PLTM.PDI_PLTM WHERE COILID = :coilid", {"coilid": coilid})
|
||||
if cursor.fetchone()[0] == 0:
|
||||
raise HTTPException(status_code=404, detail=f"钢卷 {coilid} 不存在")
|
||||
finally:
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
# 设置起始钢卷
|
||||
opc_service.set_manual_start_coil(coilid)
|
||||
|
||||
# 自动读取起始钢卷及后续3个钢卷到暂存表
|
||||
try:
|
||||
await opc_service._handle_signal1()
|
||||
except Exception as e:
|
||||
# 即使读取失败也不影响设置成功
|
||||
logger.warning(f"Failed to load initial coils after setting start coil: {e}")
|
||||
|
||||
return {"message": f"已设置起始钢卷: {coilid}"}
|
||||
|
||||
|
||||
@app.get("/api/track/available-coils")
|
||||
def get_available_coils(
|
||||
page: int = Query(1, ge=1),
|
||||
page_size: int = Query(20, ge=1, le=200),
|
||||
coilid: Optional[str] = None,
|
||||
sequencenb_min: Optional[int] = None,
|
||||
sequencenb_max: Optional[int] = None
|
||||
):
|
||||
"""获取可用的钢卷列表用于选择起始点(支持搜索和分页)"""
|
||||
conn = get_connection()
|
||||
cursor = conn.cursor()
|
||||
try:
|
||||
# 构建查询条件
|
||||
conditions = []
|
||||
params = {}
|
||||
|
||||
if coilid:
|
||||
conditions.append("COILID LIKE :coilid")
|
||||
params["coilid"] = f"%{coilid}%"
|
||||
|
||||
if sequencenb_min is not None:
|
||||
conditions.append("SEQUENCENB >= :sequencenb_min")
|
||||
params["sequencenb_min"] = sequencenb_min
|
||||
|
||||
if sequencenb_max is not None:
|
||||
conditions.append("SEQUENCENB <= :sequencenb_max")
|
||||
params["sequencenb_max"] = sequencenb_max
|
||||
|
||||
where_clause = ""
|
||||
if conditions:
|
||||
where_clause = "WHERE " + " AND ".join(conditions)
|
||||
|
||||
# 查询总数
|
||||
count_sql = f"SELECT COUNT(*) FROM PLTM.PDI_PLTM {where_clause}"
|
||||
cursor.execute(count_sql, params)
|
||||
total = cursor.fetchone()[0]
|
||||
|
||||
# 分页查询
|
||||
offset = (page - 1) * page_size
|
||||
data_sql = f"""
|
||||
SELECT COILID, SEQUENCENB, ROLLPROGRAMNB, STEEL_GRADE,
|
||||
ENTRY_COIL_THICKNESS, ENTRY_COIL_WIDTH, ENTRY_COIL_WEIGHT
|
||||
FROM PLTM.PDI_PLTM
|
||||
{where_clause}
|
||||
ORDER BY COILID ASC
|
||||
"""
|
||||
cursor.execute(data_sql, params)
|
||||
|
||||
# 手动分页(因为Oracle的ROWNUM处理比较复杂)
|
||||
all_rows = cursor.fetchall()
|
||||
paginated_rows = all_rows[offset:offset + page_size]
|
||||
|
||||
columns = [col[0].lower() for col in cursor.description]
|
||||
rows = [dict(zip(columns, row)) for row in paginated_rows]
|
||||
|
||||
return {
|
||||
"data": rows,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"page_size": page_size
|
||||
}
|
||||
finally:
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
Reference in New Issue
Block a user