from __future__ import annotations import logging from fastapi import APIRouter from fastapi.responses import Response from woc_bridge.config import _require_qr_capture, _require_send_queue from woc_bridge.messaging.ui_action_scheduler import Priority from woc_bridge.models import BridgeError logger = logging.getLogger("woc-bridge") router = APIRouter() # --------------------------------------------------------------------------- # 路由:POST /api/screenshot # --------------------------------------------------------------------------- @router.post("/api/screenshot") async def screenshot() -> Response: """截取完整屏幕并返回 PNG。 用于前端「截图」按钮 / 调试时观察微信实际界面状态(如确认 UI 操作是否 触发了正确的对话框)。截取整个 X 桌面(DISPLAY 由 _state.config.display 指定)。 Returns: Response:Content-Type=image/png,body 为 PNG 二进制 Raises: BridgeError(WINDOW_NOT_FOUND): X 会话未就绪,无法截图(HTTP 503) 其他异常由全局兜底处理器返回 BRIDGE_INTERNAL_ERROR Notes: - 截图由 qr_capture.capture_full_screenshot 完成,底层调 xdotool/getwindowgeometry + import(ImageMagick) - 与 /api/login/qr/start 区别:本接口截全屏,qr/start 截二维码区域 - 大屏幕截图可能 > 1MB,调用方注意带宽 """ logger.info("screenshot: 收到请求") qr_capture = _require_qr_capture() scheduler = _require_send_queue() try: if hasattr(scheduler, "execute"): png_bytes = await scheduler.execute( lambda: qr_capture.capture_full_screenshot(), priority=Priority.LOW, wait_timeout_ms=10000, trace_id="screenshot", ) else: png_bytes = await qr_capture.capture_full_screenshot() except BridgeError as e: logger.warning("screenshot: 失败 %s: %s", e.code, e.message) raise except Exception as e: logger.warning("screenshot: 失败 %s: %s", type(e).__name__, e) raise logger.info("screenshot: ✓ 截图成功 %d bytes", len(png_bytes)) return Response(content=png_bytes, media_type="image/png")