replace screenshot pipeline and update admin

This commit is contained in:
2025-12-31 16:50:35 +08:00
parent 2d98ab66a3
commit 41ead4bead
25 changed files with 443 additions and 2250 deletions

View File

@@ -350,7 +350,7 @@ def get_system_stats():
@admin_api_bp.route("/browser_pool/stats", methods=["GET"])
@admin_required
def get_browser_pool_stats():
"""获取浏览器池状态"""
"""获取截图线程池状态"""
try:
from browser_pool_worker import get_browser_worker_pool
@@ -408,8 +408,8 @@ def get_browser_pool_stats():
}
)
except Exception as e:
logger.exception(f"[AdminAPI] 获取浏览器池状态失败: {e}")
return jsonify({"error": "获取浏览器池状态失败"}), 500
logger.exception(f"[AdminAPI] 获取截图线程池状态失败: {e}")
return jsonify({"error": "获取截图线程池状态失败"}), 500
@admin_api_bp.route("/docker_stats", methods=["GET"])
@@ -619,7 +619,7 @@ def update_system_config_api():
if new_max_screenshot_concurrent is not None:
if not isinstance(new_max_screenshot_concurrent, int) or new_max_screenshot_concurrent < 1:
return jsonify({"error": "截图并发数必须大于0建议根据服务器配置设置每个浏览器约占用200MB内存"}), 400
return jsonify({"error": "截图并发数必须大于0建议根据服务器配置设置wkhtmltoimage 资源占用较低"}), 400
if schedule_time is not None:
import re
@@ -672,6 +672,14 @@ def update_system_config_api():
max_global=int(new_config.get("max_concurrent_global", old_config.get("max_concurrent_global", 2))),
max_per_user=int(new_config.get("max_concurrent_per_account", old_config.get("max_concurrent_per_account", 1))),
)
if new_max_screenshot_concurrent is not None:
try:
from browser_pool_worker import resize_browser_worker_pool
if resize_browser_worker_pool(int(new_config.get("max_screenshot_concurrent", new_max_screenshot_concurrent))):
logger.info(f"截图线程池并发已更新为: {new_config.get('max_screenshot_concurrent')}")
except Exception as pool_error:
logger.warning(f"截图线程池并发更新失败: {pool_error}")
except Exception:
pass

View File

@@ -295,6 +295,21 @@ def get_ip_risk(ip):
)
@security_bp.route("/api/admin/security/ip-risk/clear", methods=["POST"])
@admin_required
def clear_ip_risk():
"""清除指定IP的风险分"""
data = _parse_json()
ip_text = str(data.get("ip") or "").strip()
if not ip_text:
return jsonify({"error": "ip不能为空"}), 400
if not scorer.reset_ip_score(ip_text):
return jsonify({"error": "清理失败"}), 400
return jsonify({"success": True, "ip": _truncate(ip_text, 64), "risk_score": 0})
@security_bp.route("/api/admin/security/user-risk/<int:user_id>", methods=["GET"])
@admin_required
def get_user_risk(user_id):
@@ -331,4 +346,3 @@ def cleanup_expired():
pool_stats = None
return jsonify({"success": True, "pool_stats": pool_stats})