fix: 登录冷却期间不再显示 CTP 连接中,优化前端状态同步

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-25 16:57:06 +08:00
parent 4aebc2df49
commit 9c8b92d2bd
4 changed files with 77 additions and 14 deletions
+61 -12
View File
@@ -30,7 +30,7 @@
var selectedMaxLots = null;
var recommendMaxByProduct = {};
var recommendMaxByCode = {};
var POS_CACHE_KEY = 'qihuo_trading_live_v2';
var POS_CACHE_KEY = 'qihuo_trading_live_v3';
function runWhenReady(fn) {
if (document.readyState === 'loading') {
@@ -148,9 +148,11 @@
if (cap && data.capital != null) cap.textContent = Number(data.capital).toFixed(2);
var connected = data.ctp_status && data.ctp_status.connected;
var connecting = data.ctp_status && data.ctp_status.connecting;
var cooldownSec = (data.ctp_status && data.ctp_status.login_cooldown_sec) || 0;
if (cooldownSec > 0) connecting = false;
ctpConnected = !!connected;
isTradingSession = !!data.trading_session;
updateCtpBadge(!!connected, !!connecting);
syncCtpBadgeFromStatus(data.ctp_status || { connected: connected, connecting: connecting });
if (!connected && !connecting && data.ctp_status && data.ctp_status.last_error) {
showCtpError(data.ctp_status.last_error);
if (isCtpLoginBanError(data.ctp_status.last_error)) {
@@ -184,6 +186,11 @@
list.innerHTML = '<div class="empty-hint">CTP 连接中,请稍候…</div>';
return;
}
if (cooldownSec > 0 || (data.ctp_status && data.ctp_status.last_error)) {
var err = (data.ctp_status && data.ctp_status.last_error) || 'CTP 未连接';
list.innerHTML = '<div class="empty-hint text-loss">' + err + '</div>';
return;
}
list.innerHTML = '<div class="empty-hint">CTP 未连接,正在尝试自动重连…</div>';
tryAutoCtpReconnect();
return;
@@ -305,6 +312,16 @@
updateRRDisplay();
}
function syncCtpBadgeFromStatus(st) {
if (!st) return;
var connected = !!st.connected;
var connecting = !!st.connecting;
if ((st.login_cooldown_sec || 0) > 0) {
connecting = false;
}
updateCtpBadge(connected, connecting);
}
function updateCtpBadge(connected, connecting) {
var ctpBadge = document.getElementById('ctp-badge');
var btnConnect = document.getElementById('btn-ctp-connect');
@@ -336,7 +353,7 @@
.then(function (d) {
var st = d.status || {};
if (st.connected) {
updateCtpBadge(true, false);
syncCtpBadgeFromStatus(st);
showCtpError('');
if (d.account && d.account.available != null) {
var avail = document.getElementById('avail-display');
@@ -345,13 +362,18 @@
pollPositions();
return true;
}
if ((st.login_cooldown_sec || 0) > 0) {
syncCtpBadgeFromStatus(st);
if (st.last_error) showCtpError(st.last_error);
return false;
}
if (st.connecting && Date.now() < deadline) {
updateCtpBadge(false, true);
syncCtpBadgeFromStatus(st);
return new Promise(function (resolve) {
setTimeout(function () { resolve(tick()); }, 2000);
});
}
updateCtpBadge(false, false);
syncCtpBadgeFromStatus(st);
if (st.last_error) {
showCtpError(st.last_error);
if (isCtpLoginBanError(st.last_error)) {
@@ -380,22 +402,28 @@
})
.then(function (r) { return r.json(); })
.then(function (d) {
if (d.status && d.status.connected) {
updateCtpBadge(true, false);
var st = d.status || {};
if (st.connected) {
syncCtpBadgeFromStatus(st);
showCtpError('');
pollPositions();
return d;
}
if (d.connecting || (d.status && d.status.connecting)) {
if ((st.login_cooldown_sec || 0) > 0 || d.cooldown) {
syncCtpBadgeFromStatus(st);
showCtpError(st.last_error || d.error || 'CTP 登录冷却中');
return d;
}
if (d.connecting || st.connecting) {
return waitForCtpConnected(70000).then(function (ok) {
if (!ok && d.error) showCtpError(d.error);
else if (!ok && d.status && d.status.last_error) showCtpError(d.status.last_error);
else if (!ok && st.last_error) showCtpError(st.last_error);
return d;
});
}
if (!d.ok) {
updateCtpBadge(false, false);
var err = d.error || (d.status && d.status.last_error) || '连接失败';
syncCtpBadgeFromStatus(st);
var err = d.error || st.last_error || '连接失败';
showCtpError(err);
}
return d;
@@ -1051,6 +1079,24 @@
});
}
function initCtpOnLoad() {
fetch('/api/ctp/status')
.then(function (r) { return r.json(); })
.then(function (d) {
var st = d.status || {};
syncCtpBadgeFromStatus(st);
if (st.last_error) showCtpError(st.last_error);
if (st.connected) {
pollPositions();
return;
}
if ((st.login_cooldown_sec || 0) > 0) return;
if (isCtpLoginBanError(st.last_error)) return;
if (!st.connecting) requestCtpConnect(false);
})
.catch(function () {});
}
runWhenReady(function () {
setPriceType('limit');
if (isFixedMode() && lotsCalc) {
@@ -1059,11 +1105,14 @@
}
var cached = loadPosCache();
if (cached) {
if (cached.ctp_status) {
cached.ctp_status = Object.assign({}, cached.ctp_status, { connecting: false });
}
applyPositionsData(cached);
}
pollPositions();
connectPositionStream();
requestCtpConnect(false);
initCtpOnLoad();
connectRecommendStream();
fetch('/api/recommend/list')
.then(function (r) { return r.json(); })