From 1993c7b4b164692304e17ea874371389c27665be Mon Sep 17 00:00:00 2001 From: dekun Date: Sat, 30 May 2026 15:40:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=AD=E6=8E=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 16 +++++++ app.py | 87 ++++++++++++++++++++++++++++++++++++++ scripts/seed_gate_scout.py | 27 ++++++++++++ 部署与使用说明.md | 44 +++++++++++++++++++ 4 files changed, 174 insertions(+) create mode 100644 scripts/seed_gate_scout.py diff --git a/.env.example b/.env.example index 852a718..7a65414 100644 --- a/.env.example +++ b/.env.example @@ -42,3 +42,19 @@ # NAV_HUB_PASSWORD=你的中控密码 # 打开标记为「复盘中控」的服务时自动代登录(1=开启) # NAV_HUB_AUTO_LOGIN=1 + +# ---------- gate_scout_order(Gate 扫单,多在云服务器)---------- +# 本机 LocalNav 内嵌打开云上扫描端 / 执行器(须 Nginx 反代 + 允许 iframe,见 gate_scout 部署说明 §13) +# NAV_SEED_GATE_SCOUT=1 +# NAV_GATE_SCOUT_UPDATE=1 +# 方式 A:同一域名不同端口(防火墙已放行 8088/8090) +# NAV_GATE_SCOUT_SCHEME=https +# NAV_GATE_SCOUT_HOST=你的云服务器域名或IP +# NAV_GATE_SCOUT_PORT=8088 +# NAV_GATE_EXECUTOR_PORT=8090 +# 方式 B:两个子域名反代到 8088 / 8090(推荐,端口填 443) +# NAV_GATE_SCOUT_SCHEME=https +# NAV_GATE_SCOUT_SCOUT_HOST=scout.你的域名 +# NAV_GATE_EXECUTOR_HOST=exec.你的域名 +# NAV_GATE_SCOUT_PORT=443 +# NAV_GATE_EXECUTOR_PORT=443 diff --git a/app.py b/app.py index be99465..74a4e4b 100644 --- a/app.py +++ b/app.py @@ -222,6 +222,7 @@ def create_app() -> Flask: _migrate_schema() _ensure_default_user() _ensure_admin_from_env() + _ensure_gate_scout_services() @app.route("/login", methods=["GET", "POST"]) def login(): @@ -576,6 +577,92 @@ def _ensure_default_user() -> None: ) +def _ensure_gate_scout_services() -> None: + """gate_scout_order:扫描端 + 执行器(NAV_SEED_GATE_SCOUT=1;云服务器用域名 + https)。""" + flag = (os.environ.get("NAV_SEED_GATE_SCOUT") or "").strip().lower() + if flag not in ("1", "true", "yes", "on"): + return + + scheme = (os.environ.get("NAV_GATE_SCOUT_SCHEME") or "http").strip().lower() + if scheme not in ("http", "https"): + scheme = "http" + default_host = (os.environ.get("NAV_GATE_SCOUT_HOST") or "127.0.0.1").strip() or "127.0.0.1" + scout_host = (os.environ.get("NAV_GATE_SCOUT_SCOUT_HOST") or default_host).strip() or default_host + exec_host = (os.environ.get("NAV_GATE_EXECUTOR_HOST") or default_host).strip() or default_host + default_port = "443" if scheme == "https" else "8088" + default_exec_port = "443" if scheme == "https" else "8090" + try: + scout_port = int(os.environ.get("NAV_GATE_SCOUT_PORT") or default_port) + exec_port = int(os.environ.get("NAV_GATE_EXECUTOR_PORT") or default_exec_port) + except ValueError: + scout_port = 443 if scheme == "https" else 8088 + exec_port = 443 if scheme == "https" else 8090 + + scout_path = (os.environ.get("NAV_GATE_SCOUT_PATH") or "/dashboard").strip() or "/dashboard" + exec_path = (os.environ.get("NAV_GATE_EXECUTOR_PATH") or "/dashboard").strip() or "/dashboard" + if not scout_path.startswith("/"): + scout_path = "/" + scout_path + if not exec_path.startswith("/"): + exec_path = "/" + exec_path + + update_existing = (os.environ.get("NAV_GATE_SCOUT_UPDATE") or "").strip().lower() in ( + "1", + "true", + "yes", + "on", + ) + + group_name = (os.environ.get("NAV_GATE_SCOUT_GROUP") or "Gate 扫单").strip() or "Gate 扫单" + g = ServiceGroup.query.filter_by(name=group_name).first() + if not g: + g = ServiceGroup(name=group_name, sort_order=50) + db.session.add(g) + db.session.flush() + + defs = ( + ("Gate 扫描端", scout_host, scout_port, scout_path, 0), + ("Gate 下单执行器", exec_host, exec_port, exec_path, 10), + ) + added = 0 + updated = 0 + for name, h, port, path, order in defs: + existing = Service.query.filter_by(group_id=g.id, name=name).first() + if existing: + if update_existing and ( + existing.scheme != scheme + or existing.host != h + or existing.port != port + or existing.path != path + ): + existing.scheme = scheme + existing.host = h + existing.port = port + existing.path = path + updated += 1 + continue + db.session.add( + Service( + name=name, + scheme=scheme, + host=h, + port=port, + path=path, + sort_order=order, + group_id=g.id, + embed_kind="", + ) + ) + added += 1 + if added or updated: + db.session.commit() + print( + f"[nav] Gate 扫单:新增 {added}、更新 {updated}(分组「{group_name}」)。" + f" 扫描 {scheme}://{scout_host}:{scout_port}{scout_path};" + f"执行器 {scheme}://{exec_host}:{exec_port}{exec_path}", + flush=True, + ) + + def _ensure_admin_from_env() -> None: """库中已有用户后,.env 里的管理员账号不会自动覆盖旧库;若配置了用户名且尚不存在则补建。""" username = (os.environ.get("NAV_ADMIN_USERNAME") or "").strip() diff --git a/scripts/seed_gate_scout.py b/scripts/seed_gate_scout.py new file mode 100644 index 0000000..2b5e686 --- /dev/null +++ b/scripts/seed_gate_scout.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +"""向 LocalNav SQLite 写入 gate_scout_order 两个服务(可重复执行,已存在则跳过)。""" +from __future__ import annotations + +import os +import sys +from pathlib import Path + +_ROOT = Path(__file__).resolve().parent.parent +if str(_ROOT) not in sys.path: + sys.path.insert(0, str(_ROOT)) + +os.environ.setdefault("NAV_SEED_GATE_SCOUT", "1") + +from app import app, db # noqa: E402 +from app import _ensure_gate_scout_services # noqa: E402 + + +def main() -> None: + with app.app_context(): + _ensure_gate_scout_services() + db.session.commit() + print("完成。请刷新本地导航首页查看「Gate 扫单」分组。") + + +if __name__ == "__main__": + main() diff --git a/部署与使用说明.md b/部署与使用说明.md index 8ca5f9b..6a68707 100644 --- a/部署与使用说明.md +++ b/部署与使用说明.md @@ -276,6 +276,50 @@ HUB_EMBED_PARENT_ORIGINS=https://你的中控域名,http://192.168.x.x:5070 (`5070` 换成本地导航实际地址;与中控相同的 `HUB_BRIDGE_TOKEN` 必填。) +### 8.7 gate_scout_order(Gate 扫单)接入 + +**gate_scout 通常部署在云服务器**;本地导航在本机/局域网,通过 iframe 打开云上面板(不是 `127.0.0.1`)。 + +**1. 云上**(Nginx 反代示例): + +| 服务 | 本机端口 | 建议对外 | +|------|----------|----------| +| 扫描端 | 8088 | `https://scout.你的域名` → `127.0.0.1:8088` | +| 执行器 | 8090 | `https://exec.你的域名` → `127.0.0.1:8090` | + +进程环境变量(允许被本地导航嵌入): + +```env +NAV_ALLOW_EMBED=true +NAV_EMBED_ORIGINS=http://192.168.8.6:5070 +``` + +`5070` 换成本地访问 LocalNav 的地址(可逗号分隔多个)。 + +**2. 本机 LocalNav `.env`:** + +```env +NAV_SEED_GATE_SCOUT=1 +NAV_GATE_SCOUT_UPDATE=1 +NAV_GATE_SCOUT_SCHEME=https +NAV_GATE_SCOUT_SCOUT_HOST=scout.你的域名 +NAV_GATE_EXECUTOR_HOST=exec.你的域名 +NAV_GATE_SCOUT_PORT=443 +NAV_GATE_EXECUTOR_PORT=443 +``` + +若云上直接暴露端口、无子域名,可改用同一 `NAV_GATE_SCOUT_HOST=云IP或域名`,端口 `8088` / `8090`。 + +**3. 重启 LocalNav**,或在项目目录执行: + +```bash +NAV_SEED_GATE_SCOUT=1 NAV_GATE_SCOUT_UPDATE=1 python scripts/seed_gate_scout.py +``` + +也可在 **服务管理** 里手动改已有「Gate 扫描端」的主机与端口。 + +**4. 登录**:使用云上各服务 `config.yaml` 的 `auth` 账号密码。 + --- ## 九、部署指南(以 Ubuntu 为例)