修复前端
This commit is contained in:
@@ -1501,6 +1501,15 @@ def init_db():
|
|||||||
executed_plan_id INTEGER
|
executed_plan_id INTEGER
|
||||||
)"""
|
)"""
|
||||||
)
|
)
|
||||||
|
for ddl in (
|
||||||
|
"ALTER TABLE trend_pullback_preview_snapshots ADD COLUMN preview_created_at TEXT",
|
||||||
|
"ALTER TABLE trend_pullback_preview_snapshots ADD COLUMN outcome TEXT DEFAULT 'open'",
|
||||||
|
"ALTER TABLE trend_pullback_preview_snapshots ADD COLUMN executed_plan_id INTEGER",
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
c.execute(ddl)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
@@ -5238,18 +5247,27 @@ def render_main_page(page="trade"):
|
|||||||
trend_plans_raw = conn.execute(
|
trend_plans_raw = conn.execute(
|
||||||
"SELECT * FROM trend_pullback_plans WHERE status='active' ORDER BY id DESC"
|
"SELECT * FROM trend_pullback_plans WHERE status='active' ORDER BY id DESC"
|
||||||
).fetchall()
|
).fetchall()
|
||||||
trend_plans = [enrich_active_trend_plan_row(r) for r in trend_plans_raw]
|
trend_plans = []
|
||||||
|
for r in trend_plans_raw:
|
||||||
|
try:
|
||||||
|
trend_plans.append(enrich_active_trend_plan_row(r))
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[render_main_page] enrich trend plan: {e}")
|
||||||
|
trend_plans.append(row_to_dict(r))
|
||||||
preview_snapshots = []
|
preview_snapshots = []
|
||||||
if page == "records":
|
if page == "records":
|
||||||
snap_rows = conn.execute(
|
try:
|
||||||
f"SELECT * FROM trend_pullback_preview_snapshots WHERE {sql_list_time_field('preview_created_at')} >= ? "
|
snap_rows = conn.execute(
|
||||||
f"AND {sql_list_time_field('preview_created_at')} <= ? ORDER BY id DESC LIMIT 500",
|
f"SELECT * FROM trend_pullback_preview_snapshots WHERE {sql_list_time_field('preview_created_at')} >= ? "
|
||||||
(start_bj, end_bj),
|
f"AND {sql_list_time_field('preview_created_at')} <= ? ORDER BY id DESC LIMIT 500",
|
||||||
).fetchall()
|
(start_bj, end_bj),
|
||||||
for sr in snap_rows:
|
).fetchall()
|
||||||
sd = row_to_dict(sr)
|
for sr in snap_rows:
|
||||||
sd["outcome_label"] = preview_snapshot_outcome_label(sd.get("outcome"))
|
sd = row_to_dict(sr)
|
||||||
preview_snapshots.append(sd)
|
sd["outcome_label"] = preview_snapshot_outcome_label(sd.get("outcome"))
|
||||||
|
preview_snapshots.append(sd)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[records] trend_pullback_preview_snapshots: {e}")
|
||||||
can_trade = (
|
can_trade = (
|
||||||
trading_day_reset_allows_new_open(now)
|
trading_day_reset_allows_new_open(now)
|
||||||
and active_count < MAX_ACTIVE_POSITIONS
|
and active_count < MAX_ACTIVE_POSITIONS
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ def _find_exchange(ex_id: str) -> dict | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI(title="hub", docs_url=None, redoc_url=None)
|
app = FastAPI(title="复盘系统中控", docs_url=None, redoc_url=None)
|
||||||
STATIC_DIR = DIR / "static"
|
STATIC_DIR = DIR / "static"
|
||||||
if STATIC_DIR.is_dir():
|
if STATIC_DIR.is_dir():
|
||||||
app.mount("/assets", StaticFiles(directory=str(STATIC_DIR)), name="assets")
|
app.mount("/assets", StaticFiles(directory=str(STATIC_DIR)), name="assets")
|
||||||
|
|||||||
@@ -41,9 +41,10 @@ a:hover {
|
|||||||
|
|
||||||
/* —— 顶栏 —— */
|
/* —— 顶栏 —— */
|
||||||
.app-shell {
|
.app-shell {
|
||||||
max-width: 1280px;
|
width: 100%;
|
||||||
|
max-width: none;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 20px 48px;
|
padding: 0 clamp(16px, 2.5vw, 48px) 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-header {
|
.app-header {
|
||||||
@@ -300,10 +301,50 @@ button:disabled {
|
|||||||
|
|
||||||
.grid-monitor {
|
.grid-monitor {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr));
|
||||||
|
gap: clamp(12px, 1.2vw, 20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1400px) {
|
||||||
|
.grid-monitor {
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 2200px) {
|
||||||
|
.grid-monitor {
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-head {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trade-bar,
|
||||||
|
.toolbar,
|
||||||
|
.hint-box {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-grid-wrap {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(min(100%, 420px), 1fr));
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1600px) {
|
||||||
|
.settings-grid-wrap {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 2400px) {
|
||||||
|
.settings-grid-wrap {
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* 监控统计 */
|
/* 监控统计 */
|
||||||
.stat-row {
|
.stat-row {
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -545,12 +586,6 @@ button:disabled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* —— 系统设置 —— */
|
/* —— 系统设置 —— */
|
||||||
.settings-cards {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-card {
|
.settings-card {
|
||||||
background: var(--panel);
|
background: var(--panel);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
|
|||||||
@@ -375,7 +375,7 @@
|
|||||||
loadSettingsMetaLine();
|
loadSettingsMetaLine();
|
||||||
loadSettings().then((data) => {
|
loadSettings().then((data) => {
|
||||||
const list = document.getElementById("settings-list");
|
const list = document.getElementById("settings-list");
|
||||||
list.innerHTML = (data.exchanges || [])
|
document.getElementById("settings-list").innerHTML = (data.exchanges || [])
|
||||||
.map((ex, idx) => renderSettingsCard(ex, idx))
|
.map((ex, idx) => renderSettingsCard(ex, idx))
|
||||||
.join("");
|
.join("");
|
||||||
list.querySelectorAll(".btn-del-ex").forEach((btn) => {
|
list.querySelectorAll(".btn-del-ex").forEach((btn) => {
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title>多账户交易中控</title>
|
<title>复盘系统中控</title>
|
||||||
<link rel="stylesheet" href="/assets/app.css" />
|
<link rel="stylesheet" href="/assets/app.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-shell">
|
<div class="app-shell">
|
||||||
<header class="app-header">
|
<header class="app-header">
|
||||||
<div class="brand">交易中控 <span>manual_trading_hub</span></div>
|
<div class="brand">复盘系统中控</div>
|
||||||
<nav class="top-nav">
|
<nav class="top-nav">
|
||||||
<a href="/monitor" id="nav-monitor">监控区</a>
|
<a href="/monitor" id="nav-monitor">监控区</a>
|
||||||
<a href="/trade" id="nav-trade">下单区</a>
|
<a href="/trade" id="nav-trade">下单区</a>
|
||||||
@@ -237,7 +237,7 @@
|
|||||||
<button type="button" id="btn-settings-add">添加交易所</button>
|
<button type="button" id="btn-settings-add">添加交易所</button>
|
||||||
<button type="button" id="btn-settings-reload">重新加载</button>
|
<button type="button" id="btn-settings-reload">重新加载</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="settings-list" class="settings-cards"></div>
|
<div id="settings-list" class="settings-grid-wrap"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user