抓取生产工单,赚取发料异常
This commit is contained in:
210
web_ui/app.py
210
web_ui/app.py
@@ -44,13 +44,31 @@ BROWSER_LOGIN_DIR = BASE_DIR / "browser_login"
|
||||
browser_lock = threading.Lock()
|
||||
is_browser_busy = False
|
||||
current_task_name = ""
|
||||
task_logs = []
|
||||
|
||||
class WebLogger:
|
||||
def __init__(self, orig):
|
||||
self.orig = orig
|
||||
def write(self, text):
|
||||
self.orig.write(text)
|
||||
msg = text.strip()
|
||||
if msg and is_browser_busy:
|
||||
task_logs.append(msg)
|
||||
if len(task_logs) > 500:
|
||||
task_logs.pop(0)
|
||||
def flush(self):
|
||||
self.orig.flush()
|
||||
|
||||
sys.stdout = WebLogger(sys.stdout)
|
||||
sys.stderr = WebLogger(sys.stderr)
|
||||
|
||||
def set_browser_busy(task_name):
|
||||
"""设置浏览器为忙碌状态"""
|
||||
global is_browser_busy, current_task_name
|
||||
global is_browser_busy, current_task_name, task_logs
|
||||
with browser_lock:
|
||||
is_browser_busy = True
|
||||
current_task_name = task_name
|
||||
task_logs.clear()
|
||||
|
||||
def release_browser():
|
||||
"""释放浏览器控制权"""
|
||||
@@ -127,6 +145,16 @@ def receipts_page():
|
||||
"""渲染收货明细数据看板"""
|
||||
return render_template('index.html')
|
||||
|
||||
@app.route('/work_orders')
|
||||
def work_orders_page():
|
||||
"""渲染生产工单数据看板"""
|
||||
return render_template('work_orders.html')
|
||||
|
||||
@app.route('/abnormal_report')
|
||||
def abnormal_report_page():
|
||||
"""渲染发料异常检查数据看板"""
|
||||
return render_template('abnormal_report.html')
|
||||
|
||||
@app.route('/api/receipts')
|
||||
def get_receipts():
|
||||
"""获取收货明细数据(支持分页和多条件搜索)"""
|
||||
@@ -175,6 +203,102 @@ def get_receipts():
|
||||
"rows": [dict(ix) for ix in receipts]
|
||||
})
|
||||
|
||||
@app.route('/api/work_orders')
|
||||
def get_work_orders():
|
||||
"""获取生产工单数据(支持分页和多条件搜索)"""
|
||||
page = int(request.args.get('page', 1))
|
||||
limit = int(request.args.get('limit', 50))
|
||||
offset = (page - 1) * limit
|
||||
|
||||
# 获取搜索参数
|
||||
wo_number = request.args.get('work_orders_number', '').strip()
|
||||
material_name = request.args.get('material_name', '').strip()
|
||||
material_code = request.args.get('material_code', '').strip()
|
||||
|
||||
conn = get_db_connection()
|
||||
|
||||
# 构建动态 SQL 查询
|
||||
query_conditions = []
|
||||
params = []
|
||||
|
||||
if wo_number:
|
||||
query_conditions.append("work_orders_number LIKE ?")
|
||||
params.append(f"%{wo_number}%")
|
||||
if material_name:
|
||||
query_conditions.append("material_name LIKE ?")
|
||||
params.append(f"%{material_name}%")
|
||||
if material_code:
|
||||
query_conditions.append("material_code LIKE ?")
|
||||
params.append(f"%{material_code}%")
|
||||
|
||||
where_clause = ""
|
||||
if query_conditions:
|
||||
where_clause = " WHERE " + " AND ".join(query_conditions)
|
||||
|
||||
# 获取总数
|
||||
count_query = f"SELECT COUNT(*) FROM work_orders{where_clause}"
|
||||
total = conn.execute(count_query, params).fetchone()[0]
|
||||
|
||||
# 获取分页数据
|
||||
data_query = f"SELECT * FROM work_orders{where_clause} ORDER BY execution_time DESC LIMIT ? OFFSET ?"
|
||||
params.extend([limit, offset])
|
||||
orders = conn.execute(data_query, params).fetchall()
|
||||
|
||||
conn.close()
|
||||
|
||||
return jsonify({
|
||||
"total": total,
|
||||
"rows": [dict(ix) for ix in orders]
|
||||
})
|
||||
|
||||
@app.route('/api/abnormal_report')
|
||||
def get_abnormal_report():
|
||||
"""获取发料异常报表数据(支持分页和多条件搜索)"""
|
||||
page = int(request.args.get('page', 1))
|
||||
limit = int(request.args.get('limit', 50))
|
||||
offset = (page - 1) * limit
|
||||
|
||||
# 获取搜索参数
|
||||
wo_number = request.args.get('work_orders_number', '').strip()
|
||||
material_code = request.args.get('material_code', '').strip()
|
||||
issue_status = request.args.get('issue_status', '').strip()
|
||||
|
||||
conn = get_db_connection()
|
||||
|
||||
# 构建动态 SQL 查询
|
||||
query_conditions = []
|
||||
params = []
|
||||
|
||||
if wo_number:
|
||||
query_conditions.append("work_orders_number LIKE ?")
|
||||
params.append(f"%{wo_number}%")
|
||||
if material_code:
|
||||
query_conditions.append("material_code LIKE ?")
|
||||
params.append(f"%{material_code}%")
|
||||
if issue_status:
|
||||
query_conditions.append("issue_status = ?")
|
||||
params.append(issue_status)
|
||||
|
||||
where_clause = ""
|
||||
if query_conditions:
|
||||
where_clause = " WHERE " + " AND ".join(query_conditions)
|
||||
|
||||
# 获取总数
|
||||
count_query = f"SELECT COUNT(*) FROM abnormal_report{where_clause}"
|
||||
total = conn.execute(count_query, params).fetchone()[0]
|
||||
|
||||
# 获取分页数据 (默认按工单号倒序排列)
|
||||
data_query = f"SELECT * FROM abnormal_report{where_clause} ORDER BY work_orders_number DESC LIMIT ? OFFSET ?"
|
||||
params.extend([limit, offset])
|
||||
orders = conn.execute(data_query, params).fetchall()
|
||||
|
||||
conn.close()
|
||||
|
||||
return jsonify({
|
||||
"total": total,
|
||||
"rows": [dict(ix) for ix in orders]
|
||||
})
|
||||
|
||||
@app.route('/api/task_status')
|
||||
def get_task_status():
|
||||
"""获取当前浏览器控制任务的状态"""
|
||||
@@ -183,6 +307,11 @@ def get_task_status():
|
||||
"task_name": current_task_name
|
||||
})
|
||||
|
||||
@app.route('/api/task_logs')
|
||||
def get_task_logs():
|
||||
"""获取实时日志"""
|
||||
return jsonify({"logs": task_logs})
|
||||
|
||||
@app.route('/api/sync_receipts', methods=['POST'])
|
||||
def sync_receipts():
|
||||
"""触发后台运行收货明细增量抓取脚本(修复跨机器路径问题)"""
|
||||
@@ -222,6 +351,85 @@ def sync_receipts():
|
||||
except Exception as e:
|
||||
return jsonify({"success": False, "message": f"系统错误: {str(e)}"}), 500
|
||||
|
||||
@app.route('/api/sync_work_orders', methods=['POST'])
|
||||
def sync_work_orders():
|
||||
"""触发后台运行生产工单增量抓取脚本"""
|
||||
global is_browser_busy
|
||||
import sys
|
||||
|
||||
if is_browser_busy:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": f"系统忙碌:当前正在执行 '{current_task_name}',请稍后再试。"
|
||||
}), 409
|
||||
|
||||
if str(BROWSER_LOGIN_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(BROWSER_LOGIN_DIR))
|
||||
|
||||
def run_work_orders_sync():
|
||||
set_browser_busy("手动生产工单增量同步")
|
||||
try:
|
||||
from fetch_work_orders_incremental import fetch_work_orders_incremental
|
||||
fetch_work_orders_incremental()
|
||||
except Exception as e:
|
||||
print(f"手动生产工单同步失败: {e}")
|
||||
finally:
|
||||
release_browser()
|
||||
|
||||
try:
|
||||
threading.Thread(target=run_work_orders_sync, daemon=True).start()
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "工单增量同步任务已在后台启动!请观察黑框控制台的运行日志。",
|
||||
"logs": "任务已在后台运行..."
|
||||
})
|
||||
except ImportError:
|
||||
return jsonify({"success": False, "message": "找不到增量抓取脚本或导入失败"}), 404
|
||||
except Exception as e:
|
||||
return jsonify({"success": False, "message": f"系统错误: {str(e)}"}), 500
|
||||
|
||||
@app.route('/api/sync_abnormal_report', methods=['POST'])
|
||||
def sync_abnormal_report():
|
||||
"""触发后台运行异常报表抓取脚本"""
|
||||
global is_browser_busy
|
||||
import sys
|
||||
|
||||
if is_browser_busy:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"message": f"系统忙碌:当前正在执行 '{current_task_name}',请稍后再试。"
|
||||
}), 409
|
||||
|
||||
if str(BROWSER_LOGIN_DIR) not in sys.path:
|
||||
sys.path.insert(0, str(BROWSER_LOGIN_DIR))
|
||||
|
||||
def run_abnormal_report_sync():
|
||||
set_browser_busy("手动发料异常报表抓取")
|
||||
try:
|
||||
import auto_fetch_abnormal_report
|
||||
page = auto_fetch_abnormal_report.get_page(port=9222)
|
||||
success = auto_fetch_abnormal_report.navigate_to_report(page)
|
||||
if success:
|
||||
auto_fetch_abnormal_report.fetch_report_data(page)
|
||||
except Exception as e:
|
||||
print(f"手动发料异常报表抓取失败: {e}")
|
||||
finally:
|
||||
release_browser()
|
||||
|
||||
try:
|
||||
threading.Thread(target=run_abnormal_report_sync, daemon=True).start()
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "发料异常报表抓取任务已在后台启动!请观察黑框控制台的运行日志。",
|
||||
"logs": "任务已在后台运行..."
|
||||
})
|
||||
except ImportError:
|
||||
return jsonify({"success": False, "message": "找不到异常报表抓取脚本或导入失败"}), 404
|
||||
except Exception as e:
|
||||
return jsonify({"success": False, "message": f"系统错误: {str(e)}"}), 500
|
||||
|
||||
@app.route('/api/sync_bom', methods=['POST'])
|
||||
def sync_bom():
|
||||
"""触发后台运行 BOM 成本全量抓取脚本(修复跨机器路径问题)"""
|
||||
|
||||
Reference in New Issue
Block a user