diff --git a/app_web.py b/app_web.py index 1398a01..61260d0 100644 --- a/app_web.py +++ b/app_web.py @@ -801,6 +801,58 @@ async def save_config(request: Request): return RedirectResponse(url=app_home_url(), status_code=303) +def _logs_tail(n: int = 50) -> List[str]: + return list(service.logs)[-n:] if service.logs else [] + + +@app.post("/api/session/init") +async def api_session_init(request: Request): + """JSON 初始化:便于面板内展示结果,避免仅依赖 303 与整页刷新排错。""" + denied = json_if_console_unauthed(request) + if denied: + return denied + try: + await service.ensure_ready() + return { + "ok": True, + "connected": service.is_connected(), + "message": "Telegram 客户端已就绪。", + "logs_tail": _logs_tail(50), + } + except Exception as e: + msg = str(e) + service._append(f"初始化失败:{msg}") + return { + "ok": False, + "connected": service.is_connected(), + "error": msg, + "logs_tail": _logs_tail(50), + } + + +@app.post("/api/session/disconnect") +async def api_session_disconnect(request: Request): + denied = json_if_console_unauthed(request) + if denied: + return denied + try: + await service.disconnect() + return { + "ok": True, + "connected": service.is_connected(), + "message": "已断开 Telegram。", + "logs_tail": _logs_tail(50), + } + except Exception as e: + service._append(f"断开失败:{e}") + return { + "ok": False, + "connected": service.is_connected(), + "error": str(e), + "logs_tail": _logs_tail(50), + } + + @app.post("/start") async def start_scraper(request: Request): redir = redirect_if_console_unauthed(request) diff --git a/templates/index.html b/templates/index.html index e6595b4..129d133 100644 --- a/templates/index.html +++ b/templates/index.html @@ -868,13 +868,18 @@ {% if error %}
客户端:{{ error }}
{% endif %} +
+ 初始化可能较慢(网络、扫码登录等)。结果会显示在下方灰色框内,无需只看浏览器网络里的 303;
+ 无头登录请开 TELEGRAM_HEADLESS_QR=1 并在运行日志中打开二维码链接。
+
成功:" + + escapeHtml(data.message || "已就绪") + + "
" + ); + lines.push( + "连接状态:" + + (data.connected ? "已连接" : "未连接(请查看日志)") + + "
" + ); + } else { + var errText = + (data && data.error) || + (httpStatus && httpStatus !== 200 ? "HTTP " + httpStatus : "") || + "未知错误"; + lines.push( + "失败:" + + escapeHtml(String(errText)) + + "
" + ); + lines.push( + "连接状态:" + + (data && data.connected ? "已连接" : "未连接") + + "
" + ); + } + if (data && data.logs_tail && data.logs_tail.length) { + lines.push( + "" +
+ escapeHtml(data.logs_tail.join("\n")) +
+ ""
+ );
+ }
+ return { html: lines.join(""), isErr: !ok };
+ }
+
+ initBtn.addEventListener("click", async function () {
+ initBtn.disabled = true;
+ if (discBtn) discBtn.disabled = true;
+ showConnResult("正在连接,请稍候(扫码场景可能需数分钟)…
", false); + try { + var res = await fetch(appPath("/api/session/init"), { + method: "POST", + credentials: "same-origin", + headers: { Accept: "application/json" }, + }); + var data = await res.json().catch(function () { + return {}; + }); + var r = renderInitPayload(data, res.status); + showConnResult(r.html, r.isErr); + await refreshStatus(); + } catch (e) { + showConnResult( + "请求失败:" + + escapeHtml(e && e.message ? e.message : String(e)) + + "
", + true + ); + } finally { + initBtn.disabled = false; + if (discBtn) discBtn.disabled = false; + } + }); + + if (discBtn) { + discBtn.addEventListener("click", async function () { + initBtn.disabled = true; + discBtn.disabled = true; + showConnResult("正在断开…
", false); + try { + var res = await fetch(appPath("/api/session/disconnect"), { + method: "POST", + credentials: "same-origin", + headers: { Accept: "application/json" }, + }); + var data = await res.json().catch(function () { + return {}; + }); + var ok = data && data.ok === true; + var lines = []; + if (ok) { + lines.push( + "" + + escapeHtml(data.message || "已断开") + + "
" + ); + } else { + lines.push( + "失败:" + + escapeHtml((data && data.error) || "未知错误") + + "
" + ); + } + if (data && data.logs_tail && data.logs_tail.length) { + lines.push( + "" +
+ escapeHtml(data.logs_tail.join("\n")) +
+ ""
+ );
+ }
+ showConnResult(lines.join(""), !ok);
+ await refreshStatus();
+ } catch (e) {
+ showConnResult(
+ "请求失败:" + + escapeHtml(e && e.message ? e.message : String(e)) + + "
", + true + ); + } finally { + initBtn.disabled = false; + discBtn.disabled = false; + } + }); + } + })(); + (function () { var form = document.querySelector(".account-pick-form"); if (!form) return;