Persist options review deletes across local resync.

Hide deleted rows by history key and contract/close fingerprint so local options_trades imports no longer resurrect them.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-17 10:03:00 +08:00
parent 48afc8ebe3
commit d7272c9722
9 changed files with 339 additions and 14 deletions
+25 -5
View File
@@ -1831,12 +1831,19 @@
}
}
async function deleteHistoryRow(key, status) {
async function deleteHistoryRow(key, status, instId, closedAt) {
const warn = status === "open"
? "该记录仍为持仓中,仅从列表隐藏,不影响交易所持仓.确认删除?"
: "确认从列表隐藏该条历史记录?";
: "确认从列表隐藏该条历史记录?(期权复盘页也会同步隐藏)";
if (!confirm(warn)) return;
const r = await apiJson("/api/options/history/" + encodeURIComponent(key), { method: "DELETE" });
const body = {};
if (instId) body.inst_id = instId;
if (closedAt) body.closed_at = closedAt;
const r = await apiJson("/api/options/history/" + encodeURIComponent(key), {
method: "DELETE",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (!r.ok) {
alert(r.msg || "删除失败");
return;
@@ -1885,12 +1892,25 @@
"<td>" + optHistoryStatusHtml(h) + "</td>" +
'<td class="' + pnlCls + '">' + pnlTxt + "</td>" +
'<td class="opt-hist-time">' + timeTxt + "</td>" +
'<td><button type="button" class="btn-secondary btn-sm opt-history-del" data-key="' + histKey + '" data-status="' + (h.status || "") + '">删除</button></td>';
'<td><button type="button" class="btn-secondary btn-sm opt-history-del" data-key="' +
histKey +
'" data-status="' +
(h.status || "") +
'" data-inst="' +
(h.inst_id || "") +
'" data-closed="' +
(h.closed_at || h.created_at || "") +
'">删除</button></td>';
tbody.appendChild(tr);
});
tbody.querySelectorAll(".opt-history-del").forEach(function (btn) {
btn.addEventListener("click", function () {
deleteHistoryRow(btn.getAttribute("data-key"), btn.getAttribute("data-status"));
deleteHistoryRow(
btn.getAttribute("data-key"),
btn.getAttribute("data-status"),
btn.getAttribute("data-inst"),
btn.getAttribute("data-closed")
);
});
});
}
+39 -5
View File
@@ -94,7 +94,7 @@
function loadTrades() {
var tbody = $("or-trades-tbody");
if (!tbody) return;
tbody.innerHTML = '<tr><td colspan="7" class="muted">加载中…</td></tr>';
tbody.innerHTML = '<tr><td colspan="8" class="muted">加载中…</td></tr>';
fetch("/api/options/review/trades?" + qs(), { credentials: "same-origin" })
.then(function (r) {
return r.json();
@@ -102,14 +102,14 @@
.then(function (data) {
setSyncStatus("本地记录已加载");
if (!data.ok) {
tbody.innerHTML = '<tr><td colspan="7" class="muted">加载失败</td></tr>';
tbody.innerHTML = '<tr><td colspan="8" class="muted">加载失败</td></tr>';
return;
}
var rows = data.trades || [];
tradesCache = {};
if (!rows.length) {
tbody.innerHTML =
'<tr><td colspan="7" class="muted">暂无本地已平记录(期权页平仓后或对冲计划结束后会出现在此)</td></tr>';
'<tr><td colspan="8" class="muted">暂无本地已平记录(期权页平仓后或对冲计划结束后会出现在此)</td></tr>';
return;
}
tbody.innerHTML = rows
@@ -159,18 +159,29 @@
"<td>" +
(t.reviewed ? "已复盘" : "待复盘") +
"</td>" +
'<td><button type="button" class="btn-secondary or-hide-btn" data-id="' +
t.id +
'" style="font-size:.72rem;padding:2px 8px">删除</button></td>' +
"</tr>"
);
})
.join("");
tbody.querySelectorAll(".or-trade-row").forEach(function (tr) {
tr.addEventListener("click", function () {
tr.addEventListener("click", function (ev) {
if (ev.target && ev.target.closest && ev.target.closest(".or-hide-btn")) return;
openJournalForm(Number(tr.getAttribute("data-id")));
});
});
tbody.querySelectorAll(".or-hide-btn").forEach(function (btn) {
btn.addEventListener("click", function (ev) {
ev.preventDefault();
ev.stopPropagation();
hideTrade(Number(btn.getAttribute("data-id")));
});
});
})
.catch(function () {
tbody.innerHTML = '<tr><td colspan="7" class="muted">加载失败</td></tr>';
tbody.innerHTML = '<tr><td colspan="8" class="muted">加载失败</td></tr>';
});
}
@@ -491,6 +502,29 @@
}
}
function hideTrade(tradeId) {
if (!tradeId) return;
if (!confirm("从复盘列表删除并隐藏?刷新后也不会再出现.")) return;
fetch("/api/options/review/trades/" + tradeId, {
method: "DELETE",
credentials: "same-origin",
})
.then(function (r) {
return r.json();
})
.then(function (data) {
if (!data.ok) {
alert(data.msg || "删除失败");
return;
}
if (currentTradeId === tradeId) hideJournalForm();
reloadAll();
})
.catch(function () {
alert("删除失败");
});
}
function saveEntry() {
var tradeId = Number(($("or-trade-id") || {}).value || 0);
if (!tradeId) {