第一期骨架:登录、实例登记、多机总览、内嵌/新标签打开。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-01 10:54:07 +08:00
parent 55e77d6b2b
commit d20acaf852
17 changed files with 881 additions and 2 deletions
+29
View File
@@ -0,0 +1,29 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}期权中控{% endblock %}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='hub.css') }}">
</head>
<body>
{% if session.get('logged_in') %}
<header class="topbar">
<div class="brand">crypto_okx_hub</div>
<nav>
<a href="/" class="{% if request.path == '/' %}active{% endif %}">总览</a>
<a href="/instances" class="{% if request.path.startswith('/instances') %}active{% endif %}">实例</a>
<a href="/desk" class="{% if request.path.startswith('/desk') %}active{% endif %}">工作台</a>
<a href="/logout">退出</a>
</nav>
</header>
{% endif %}
<main class="main">
{% with messages = get_flashed_messages() %}
{% if messages %}<div class="flash">{{ messages[0] }}</div>{% endif %}
{% endwith %}
{% block body %}{% endblock %}
</main>
{% block scripts %}{% endblock %}
</body>
</html>
+14
View File
@@ -0,0 +1,14 @@
{% extends "base.html" %}
{% block title %}总览 · 期权中控{% endblock %}
{% block body %}
<section class="page-head">
<h1>多机持仓总览</h1>
<button type="button" class="btn" id="btn-refresh">刷新</button>
</section>
<p class="muted" id="overview-status">加载中…</p>
<div id="overview-grid" class="card-grid"></div>
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='hub.js') }}"></script>
<script>HubOverview.boot();</script>
{% endblock %}
+31
View File
@@ -0,0 +1,31 @@
{% extends "base.html" %}
{% block title %}工作台 · 期权中控{% endblock %}
{% block body %}
<section class="desk">
<aside class="desk-side">
<h2>客户端</h2>
<ul class="desk-list">
{% for inst in instances %}
<li class="{% if current and current.id == inst.id %}active{% endif %}">
<a href="/desk?id={{ inst.id }}">{{ inst.name }}</a>
</li>
{% else %}
<li class="muted">无启用实例</li>
{% endfor %}
</ul>
</aside>
<div class="desk-main">
{% if current and open_url %}
<div class="desk-toolbar">
<strong>{{ current.name }}</strong>
<span class="muted">{{ current.base_url }}</span>
<a class="btn" href="{{ open_url }}" target="_blank" rel="noopener">新标签打开</a>
<a class="btn" href="/" >回总览</a>
</div>
<iframe class="desk-frame" src="{{ open_url }}" title="{{ current.name }}"></iframe>
{% else %}
<div class="empty">请从左侧选择客户端,或到「实例」添加公网 crypto_okx.</div>
{% endif %}
</div>
</section>
{% endblock %}
+54
View File
@@ -0,0 +1,54 @@
{% extends "base.html" %}
{% block title %}实例 · 期权中控{% endblock %}
{% block body %}
<section class="page-head"><h1>客户端实例</h1></section>
<section class="panel">
<h2>添加实例</h2>
<form method="post" class="form-grid">
<input type="hidden" name="action" value="create">
<label>名称 <input name="name" required placeholder="ETH-主策略"></label>
<label>公网 URL <input name="base_url" required placeholder="https://okx-eth.example.com"></label>
<label>Bridge Token <input name="bridge_token" required placeholder="与客户端 HUB_BRIDGE_TOKEN 一致"></label>
<label>Embed 路径 <input name="embed_path" value="/embed"></label>
<label>标签 <input name="tags" placeholder="eth,sim"></label>
<label class="check"><input type="checkbox" name="enabled" value="1" checked> 启用拉取</label>
<button type="submit">添加</button>
</form>
</section>
<section class="panel">
<h2>已登记 ({{ instances|length }})</h2>
{% if not instances %}
<p class="muted">暂无实例.先在 crypto_okx 配置 HUB_BRIDGE_TOKEN 并公网可访问.</p>
{% endif %}
{% for inst in instances %}
<details class="inst-row">
<summary>
<strong>{{ inst.name }}</strong>
<span class="muted">{{ inst.base_url }}</span>
{% if inst.enabled %}启用{% else %}停用{% endif %}
</summary>
<form method="post" class="form-grid">
<input type="hidden" name="action" value="update">
<input type="hidden" name="id" value="{{ inst.id }}">
<label>名称 <input name="name" value="{{ inst.name }}" required></label>
<label>公网 URL <input name="base_url" value="{{ inst.base_url }}" required></label>
<label>Bridge Token <input name="bridge_token" value="{{ inst.bridge_token }}" required></label>
<label>Embed 路径 <input name="embed_path" value="{{ inst.embed_path }}"></label>
<label>标签 <input name="tags" value="{{ inst.tags or '' }}"></label>
<label class="check"><input type="checkbox" name="enabled" value="1" {% if inst.enabled %}checked{% endif %}> 启用</label>
<button type="submit">保存</button>
</form>
<form method="post" class="inline" onsubmit="return confirm('确认删除?')">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="{{ inst.id }}">
<button type="submit" class="btn-danger">删除</button>
</form>
<p>
<a class="btn" href="/desk?id={{ inst.id }}">内嵌打开</a>
</p>
</details>
{% endfor %}
</section>
{% endblock %}
+13
View File
@@ -0,0 +1,13 @@
{% extends "base.html" %}
{% block title %}登录 · 期权中控{% endblock %}
{% block body %}
<section class="login-card">
<h1>期权中控登录</h1>
<p class="muted">关联客户端仓库 crypto_okx · 本仓不下单</p>
<form method="post" class="stack">
<label>用户名 <input name="username" autocomplete="username" required></label>
<label>密码 <input type="password" name="password" autocomplete="current-password" required></label>
<button type="submit">登录</button>
</form>
</section>
{% endblock %}