Restructure options review into pending trades, form, and reviewed detail.
Show five pending trades per page, reveal the upload form only after clicking 复盘, and list saved reviews with image detail above stats. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* OKX 期权复盘:三类 Tab + 列表点选 + 下方多周期(5m/15m/1h/4h)复盘表单.
|
||||
* OKX 期权复盘:待复盘交易(5行) → 点复盘出表单 → 复盘记录详情 → 统计.
|
||||
*/
|
||||
(function (global) {
|
||||
"use strict";
|
||||
|
||||
var SLOT_TFS = ["5m", "15m", "1h", "4h"];
|
||||
var PAGE_SIZE = 5;
|
||||
var TAB_LABELS = {
|
||||
option_spot: "期权交易记录",
|
||||
options_options: "期期对冲记录",
|
||||
@@ -27,11 +27,22 @@
|
||||
var currentTradeId = null;
|
||||
var draftId = "";
|
||||
var tradesCache = {};
|
||||
var reviewedCache = {};
|
||||
var tradesPage = 0;
|
||||
var tradesHasMore = false;
|
||||
|
||||
function $(id) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
||||
function escapeHtml(s) {
|
||||
return String(s == null ? "" : s)
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """);
|
||||
}
|
||||
|
||||
function fmtPnl(v) {
|
||||
if (v == null || v === "") return "—";
|
||||
var n = Number(v);
|
||||
@@ -54,6 +65,23 @@
|
||||
return s;
|
||||
}
|
||||
|
||||
function tradeTitle(t) {
|
||||
if (!t) return "—";
|
||||
if (t.source_type === "option_spot") return t.inst_id || "—";
|
||||
return (
|
||||
(t.underlying || "") +
|
||||
(t.direction ? " " + t.direction : "") +
|
||||
(t.plan_close_reason ? " · " + t.plan_close_reason : "")
|
||||
);
|
||||
}
|
||||
|
||||
function pnlStyle(v) {
|
||||
var n = Number(v);
|
||||
if (n > 0) return "color:#3dd68c";
|
||||
if (n < 0) return "color:#f07178";
|
||||
return "";
|
||||
}
|
||||
|
||||
function newDraftId() {
|
||||
if (global.crypto && typeof global.crypto.randomUUID === "function") {
|
||||
return global.crypto.randomUUID().replace(/-/g, "");
|
||||
@@ -63,23 +91,21 @@
|
||||
return s;
|
||||
}
|
||||
|
||||
function qs() {
|
||||
function baseQs() {
|
||||
var p = new URLSearchParams();
|
||||
p.set("source_type", activeSource);
|
||||
var uly = ($("or-filter-uly") || {}).value || "";
|
||||
var opt = ($("or-filter-opt") || {}).value || "";
|
||||
var reviewed = ($("or-filter-reviewed") || {}).value || "";
|
||||
var strategy = (($("or-filter-strategy") || {}).value || "").trim();
|
||||
var from = ($("or-filter-from") || {}).value || "";
|
||||
var to = ($("or-filter-to") || {}).value || "";
|
||||
if (uly) p.set("underlying", uly);
|
||||
if (opt) p.set("opt_type", opt);
|
||||
if (reviewed) p.set("reviewed", reviewed);
|
||||
if (strategy) p.set("strategy_tag", strategy);
|
||||
if (from) p.set("closed_from", from.replace("T", " ") + ":00");
|
||||
if (to) p.set("closed_to", to.replace("T", " ") + ":00");
|
||||
if (($("or-include-hedge-legs") || {}).checked) p.set("include_hedge_legs", "1");
|
||||
return p.toString();
|
||||
return p;
|
||||
}
|
||||
|
||||
function setSyncStatus(text) {
|
||||
@@ -90,6 +116,7 @@
|
||||
function reloadAll() {
|
||||
setSyncStatus("读取本地记录…");
|
||||
loadTrades();
|
||||
loadReviewed();
|
||||
loadStats();
|
||||
}
|
||||
|
||||
@@ -170,6 +197,7 @@
|
||||
|
||||
function setActiveTab(source) {
|
||||
activeSource = source || "option_spot";
|
||||
tradesPage = 0;
|
||||
document.querySelectorAll(".or-tab").forEach(function (btn) {
|
||||
btn.classList.toggle("active", btn.getAttribute("data-source") === activeSource);
|
||||
});
|
||||
@@ -177,45 +205,49 @@
|
||||
if (title) title.textContent = TAB_LABELS[activeSource] || "记录";
|
||||
applyFormPresets(activeSource);
|
||||
hideJournalForm();
|
||||
hideDetail();
|
||||
reloadAll();
|
||||
}
|
||||
|
||||
function updateTradesPager() {
|
||||
var label = $("or-trades-page-label");
|
||||
var prev = $("or-trades-prev");
|
||||
var next = $("or-trades-next");
|
||||
if (label) label.textContent = "第 " + (tradesPage + 1) + " 页";
|
||||
if (prev) prev.disabled = tradesPage <= 0;
|
||||
if (next) next.disabled = !tradesHasMore;
|
||||
}
|
||||
|
||||
function loadTrades() {
|
||||
var tbody = $("or-trades-tbody");
|
||||
if (!tbody) return;
|
||||
tbody.innerHTML = '<tr><td colspan="8" class="muted">加载中…</td></tr>';
|
||||
fetch("/api/options/review/trades?" + qs(), { credentials: "same-origin" })
|
||||
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载中…</td></tr>';
|
||||
var p = baseQs();
|
||||
p.set("reviewed", "0");
|
||||
p.set("limit", String(PAGE_SIZE));
|
||||
p.set("offset", String(tradesPage * PAGE_SIZE));
|
||||
fetch("/api/options/review/trades?" + p.toString(), { credentials: "same-origin" })
|
||||
.then(function (r) {
|
||||
return r.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
setSyncStatus("本地记录已加载");
|
||||
if (!data.ok) {
|
||||
tbody.innerHTML = '<tr><td colspan="8" class="muted">加载失败</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载失败</td></tr>';
|
||||
return;
|
||||
}
|
||||
var rows = data.trades || [];
|
||||
tradesHasMore = rows.length >= PAGE_SIZE;
|
||||
tradesCache = {};
|
||||
updateTradesPager();
|
||||
if (!rows.length) {
|
||||
tbody.innerHTML =
|
||||
'<tr><td colspan="8" class="muted">暂无本地已平记录(期权页平仓后或对冲计划结束后会出现在此)</td></tr>';
|
||||
'<tr><td colspan="6" class="muted">暂无待复盘记录</td></tr>';
|
||||
return;
|
||||
}
|
||||
tbody.innerHTML = rows
|
||||
.map(function (t) {
|
||||
tradesCache[t.id] = t;
|
||||
var title =
|
||||
t.source_type === "option_spot"
|
||||
? t.inst_id || "—"
|
||||
: (t.underlying || "") +
|
||||
(t.direction ? " " + t.direction : "") +
|
||||
(t.plan_close_reason ? " · " + t.plan_close_reason : "");
|
||||
var pnlClass =
|
||||
Number(t.realized_pnl_total) > 0
|
||||
? "color:#3dd68c"
|
||||
: Number(t.realized_pnl_total) < 0
|
||||
? "color:#f07178"
|
||||
: "";
|
||||
var active = currentTradeId === t.id ? " or-row-active" : "";
|
||||
return (
|
||||
'<tr class="or-trade-row' +
|
||||
@@ -224,41 +256,39 @@
|
||||
t.id +
|
||||
'">' +
|
||||
"<td><span class=\"or-badge\">" +
|
||||
(t.source_label || t.source_type) +
|
||||
escapeHtml(t.source_label || t.source_type) +
|
||||
"</span></td>" +
|
||||
"<td>" +
|
||||
title +
|
||||
escapeHtml(tradeTitle(t)) +
|
||||
"</td>" +
|
||||
'<td style="' +
|
||||
pnlClass +
|
||||
pnlStyle(t.realized_pnl_total) +
|
||||
'">' +
|
||||
fmtPnl(t.realized_pnl_total) +
|
||||
"</td>" +
|
||||
'<td class="muted" style="font-size:12px">' +
|
||||
(t.opened_at || "—") +
|
||||
escapeHtml(t.opened_at || "—") +
|
||||
"<br>" +
|
||||
(t.closed_at || "—") +
|
||||
escapeHtml(t.closed_at || "—") +
|
||||
"</td>" +
|
||||
"<td>" +
|
||||
fmtHold(t.hold_seconds) +
|
||||
"</td>" +
|
||||
"<td>" +
|
||||
(t.strategy_tag || "—") +
|
||||
"</td>" +
|
||||
"<td>" +
|
||||
(t.reviewed ? "已复盘" : "待复盘") +
|
||||
"</td>" +
|
||||
'<td><button type="button" class="btn-secondary or-hide-btn" data-id="' +
|
||||
'<td><button type="button" class="btn or-review-btn" data-id="' +
|
||||
t.id +
|
||||
'" style="font-size:.72rem;padding:2px 8px">复盘</button> ' +
|
||||
'<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 (ev) {
|
||||
if (ev.target && ev.target.closest && ev.target.closest(".or-hide-btn")) return;
|
||||
openJournalForm(Number(tr.getAttribute("data-id")));
|
||||
tbody.querySelectorAll(".or-review-btn").forEach(function (btn) {
|
||||
btn.addEventListener("click", function (ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
openJournalForm(Number(btn.getAttribute("data-id")));
|
||||
});
|
||||
});
|
||||
tbody.querySelectorAll(".or-hide-btn").forEach(function (btn) {
|
||||
@@ -270,10 +300,217 @@
|
||||
});
|
||||
})
|
||||
.catch(function () {
|
||||
tbody.innerHTML = '<tr><td colspan="8" class="muted">加载失败</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载失败</td></tr>';
|
||||
});
|
||||
}
|
||||
|
||||
function loadReviewed() {
|
||||
var tbody = $("or-reviewed-tbody");
|
||||
if (!tbody) return;
|
||||
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载中…</td></tr>';
|
||||
var p = baseQs();
|
||||
p.set("reviewed", "1");
|
||||
p.set("limit", "100");
|
||||
p.set("offset", "0");
|
||||
fetch("/api/options/review/trades?" + p.toString(), { credentials: "same-origin" })
|
||||
.then(function (r) {
|
||||
return r.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
if (!data.ok) {
|
||||
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载失败</td></tr>';
|
||||
return;
|
||||
}
|
||||
var rows = data.trades || [];
|
||||
reviewedCache = {};
|
||||
if (!rows.length) {
|
||||
tbody.innerHTML = '<tr><td colspan="6" class="muted">暂无复盘记录</td></tr>';
|
||||
return;
|
||||
}
|
||||
tbody.innerHTML = rows
|
||||
.map(function (t) {
|
||||
reviewedCache[t.id] = t;
|
||||
return (
|
||||
'<tr class="or-reviewed-row" data-id="' +
|
||||
t.id +
|
||||
'">' +
|
||||
"<td><span class=\"or-badge\">" +
|
||||
escapeHtml(t.source_label || t.source_type) +
|
||||
"</span></td>" +
|
||||
"<td>" +
|
||||
escapeHtml(tradeTitle(t)) +
|
||||
"</td>" +
|
||||
'<td style="' +
|
||||
pnlStyle(t.realized_pnl_total) +
|
||||
'">' +
|
||||
fmtPnl(t.realized_pnl_total) +
|
||||
"</td>" +
|
||||
"<td>" +
|
||||
escapeHtml(t.strategy_tag || "—") +
|
||||
"</td>" +
|
||||
"<td>" +
|
||||
escapeHtml(t.result_tag || "—") +
|
||||
"</td>" +
|
||||
'<td class="muted" style="font-size:12px">' +
|
||||
escapeHtml(t.reviewed_at || "—") +
|
||||
"</td>" +
|
||||
"</tr>"
|
||||
);
|
||||
})
|
||||
.join("");
|
||||
tbody.querySelectorAll(".or-reviewed-row").forEach(function (tr) {
|
||||
tr.addEventListener("click", function () {
|
||||
openDetail(Number(tr.getAttribute("data-id")));
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(function () {
|
||||
tbody.innerHTML = '<tr><td colspan="6" class="muted">加载失败</td></tr>';
|
||||
});
|
||||
}
|
||||
|
||||
function hideDetail() {
|
||||
var panel = $("or-detail-panel");
|
||||
if (panel) panel.classList.add("hidden");
|
||||
}
|
||||
|
||||
function openDetail(tradeId) {
|
||||
var panel = $("or-detail-panel");
|
||||
if (!panel) return;
|
||||
panel.classList.remove("hidden");
|
||||
($("or-detail-title") || {}).textContent = "加载中…";
|
||||
($("or-detail-meta") || {}).innerHTML = "";
|
||||
($("or-detail-text") || {}).innerHTML = "";
|
||||
($("or-detail-images") || {}).innerHTML = "";
|
||||
panel.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
||||
|
||||
fetch("/api/options/review/trades/" + tradeId, { credentials: "same-origin" })
|
||||
.then(function (r) {
|
||||
return r.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
if (!data.ok || !data.trade) {
|
||||
($("or-detail-title") || {}).textContent = "加载失败";
|
||||
return;
|
||||
}
|
||||
renderDetail(data.trade);
|
||||
})
|
||||
.catch(function () {
|
||||
($("or-detail-title") || {}).textContent = "加载失败";
|
||||
});
|
||||
}
|
||||
|
||||
function renderDetail(t) {
|
||||
var e = t.entry || {};
|
||||
reviewedCache[t.id] = t;
|
||||
($("or-detail-title") || {}).textContent =
|
||||
"复盘详情 · " + (t.source_label || "") + " · " + tradeTitle(t);
|
||||
var editBtn = $("or-detail-edit-btn");
|
||||
if (editBtn) editBtn.setAttribute("data-id", String(t.id));
|
||||
|
||||
var meta = $("or-detail-meta");
|
||||
if (meta) {
|
||||
var cells = [
|
||||
["标的", t.underlying || "—"],
|
||||
["合约/计划", tradeTitle(t)],
|
||||
["盈亏", fmtPnl(t.realized_pnl_total)],
|
||||
["持有", fmtHold(t.hold_seconds)],
|
||||
["开仓", t.opened_at || "—"],
|
||||
["平仓", t.closed_at || "—"],
|
||||
["策略", e.strategy_tag || "—"],
|
||||
["方向", e.direction_view || "—"],
|
||||
["结果", e.result_tag || "—"],
|
||||
["离场", e.exit_reason || "—"],
|
||||
["按计划", e.followed_plan || "—"],
|
||||
["入场逻辑", e.entry_logic || "—"],
|
||||
];
|
||||
if (t.is_hedge) {
|
||||
cells.push(["永续盈亏", fmtPnl(t.realized_pnl_perp)]);
|
||||
cells.push(["期权盈亏", fmtPnl(t.realized_pnl_options)]);
|
||||
}
|
||||
meta.innerHTML = cells
|
||||
.map(function (pair) {
|
||||
return (
|
||||
"<div><div class=\"muted\" style=\"font-size:11px\">" +
|
||||
escapeHtml(pair[0]) +
|
||||
"</div><div>" +
|
||||
escapeHtml(pair[1]) +
|
||||
"</div></div>"
|
||||
);
|
||||
})
|
||||
.join("");
|
||||
}
|
||||
|
||||
var text = $("or-detail-text");
|
||||
if (text) {
|
||||
var lines = [];
|
||||
if (e.mistake_tags) lines.push("<div><b>心理标签</b>:" + escapeHtml(e.mistake_tags) + "</div>");
|
||||
if (e.note) lines.push("<div><b>备注</b>:" + escapeHtml(e.note).replace(/\n/g, "<br>") + "</div>");
|
||||
if (t.legs && t.legs.length) {
|
||||
lines.push(
|
||||
"<div style=\"margin-top:6px\"><b>计划腿</b></div><table class=\"options-strike-table\"><thead><tr><th>腿</th><th>合约</th><th>盈亏</th><th>原因</th></tr></thead><tbody>" +
|
||||
t.legs
|
||||
.map(function (leg) {
|
||||
return (
|
||||
"<tr><td>" +
|
||||
escapeHtml(leg.leg_role || "") +
|
||||
"</td><td>" +
|
||||
escapeHtml(leg.inst_id || leg.symbol || "") +
|
||||
"</td><td>" +
|
||||
fmtPnl(leg.realized_pnl) +
|
||||
"</td><td>" +
|
||||
escapeHtml(leg.close_reason || "") +
|
||||
"</td></tr>"
|
||||
);
|
||||
})
|
||||
.join("") +
|
||||
"</tbody></table>"
|
||||
);
|
||||
}
|
||||
text.innerHTML = lines.join("") || '<div class="muted">无额外备注</div>';
|
||||
}
|
||||
|
||||
var imagesHost = $("or-detail-images");
|
||||
if (imagesHost) {
|
||||
var images = e.images || [];
|
||||
if (!images.length) {
|
||||
imagesHost.innerHTML = '<div class="muted">无截图</div>';
|
||||
} else {
|
||||
imagesHost.innerHTML = images
|
||||
.map(function (img) {
|
||||
var file = String(img.file || "").trim();
|
||||
if (!file) return "";
|
||||
var src = "/static/images/options_journal/" + encodeURIComponent(file).replace(/%2F/g, "/");
|
||||
var label = escapeHtml(img.tf || "截图");
|
||||
return (
|
||||
'<div class="or-detail-img-cell">' +
|
||||
'<span class="or-detail-img-label">' +
|
||||
label +
|
||||
"</span>" +
|
||||
'<img class="or-detail-img-thumb" src="' +
|
||||
src +
|
||||
'" alt="' +
|
||||
label +
|
||||
'" data-src="' +
|
||||
src +
|
||||
'">' +
|
||||
"</div>"
|
||||
);
|
||||
})
|
||||
.join("");
|
||||
imagesHost.querySelectorAll("img").forEach(function (img) {
|
||||
img.addEventListener("click", function () {
|
||||
if (typeof global.showImage === "function") {
|
||||
global.showImage(img.getAttribute("data-src"));
|
||||
} else {
|
||||
global.open(img.getAttribute("data-src"), "_blank");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function renderGroup(title, items) {
|
||||
if (!items || !items.length) {
|
||||
return (
|
||||
@@ -288,7 +525,7 @@
|
||||
return (
|
||||
'<div style="display:flex;justify-content:space-between;gap:8px;font-size:13px">' +
|
||||
"<span>" +
|
||||
g.key +
|
||||
escapeHtml(g.key) +
|
||||
" · " +
|
||||
g.count +
|
||||
"笔</span>" +
|
||||
@@ -314,7 +551,7 @@
|
||||
var kpi = $("or-kpi");
|
||||
var groups = $("or-stats-groups");
|
||||
if (!kpi || !groups) return;
|
||||
fetch("/api/options/review/stats?" + qs(), { credentials: "same-origin" })
|
||||
fetch("/api/options/review/stats?" + baseQs().toString(), { credentials: "same-origin" })
|
||||
.then(function (r) {
|
||||
return r.json();
|
||||
})
|
||||
@@ -372,7 +609,7 @@
|
||||
input.dataset.orBound = "1";
|
||||
input.addEventListener("change", function () {
|
||||
var file = input.files && input.files[0];
|
||||
var row = input.closest(".or-upload-row");
|
||||
var row = input.closest(".journal-upload-row");
|
||||
var status = row && row.querySelector(".or-upload-status");
|
||||
var hidden = row && row.querySelector(".or-upload-hidden");
|
||||
if (!file) {
|
||||
@@ -456,7 +693,7 @@
|
||||
function hideJournalForm() {
|
||||
currentTradeId = null;
|
||||
var card = $("or-journal-card");
|
||||
if (card) card.classList.add("or-journal-idle");
|
||||
if (card) card.classList.add("hidden");
|
||||
document.querySelectorAll(".or-trade-row").forEach(function (tr) {
|
||||
tr.classList.remove("or-row-active");
|
||||
});
|
||||
@@ -478,8 +715,7 @@
|
||||
resetUploadSlots();
|
||||
var summary = $("or-journal-summary");
|
||||
if (summary) {
|
||||
summary.textContent =
|
||||
"点下方列表一笔记录自动填入;截图槽位与合约复盘相同(5m / 15m / 1h / 4h).";
|
||||
summary.textContent = "截图槽位与合约复盘相同(5m / 15m / 1h / 4h).";
|
||||
}
|
||||
var legsHost = $("or-legs-host");
|
||||
if (legsHost) legsHost.innerHTML = "";
|
||||
@@ -490,7 +726,7 @@
|
||||
currentTradeId = tradeId;
|
||||
var card = $("or-journal-card");
|
||||
if (!card) return;
|
||||
card.classList.remove("or-journal-idle");
|
||||
card.classList.remove("hidden");
|
||||
card.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||
document.querySelectorAll(".or-trade-row").forEach(function (tr) {
|
||||
tr.classList.toggle("or-row-active", Number(tr.getAttribute("data-id")) === tradeId);
|
||||
@@ -551,7 +787,6 @@
|
||||
: "");
|
||||
}
|
||||
|
||||
// 已有截图回填状态(文件名保留,新上传会换 draft)
|
||||
(e.images || []).forEach(function (img) {
|
||||
var hidden = document.querySelector(
|
||||
'#or-upload-slots .or-upload-hidden[data-tf="' + img.tf + '"]'
|
||||
@@ -574,13 +809,13 @@
|
||||
.map(function (leg) {
|
||||
return (
|
||||
"<tr><td>" +
|
||||
(leg.leg_role || "") +
|
||||
escapeHtml(leg.leg_role || "") +
|
||||
"</td><td>" +
|
||||
(leg.inst_id || leg.symbol || "") +
|
||||
escapeHtml(leg.inst_id || leg.symbol || "") +
|
||||
"</td><td>" +
|
||||
fmtPnl(leg.realized_pnl) +
|
||||
"</td><td>" +
|
||||
(leg.close_reason || "") +
|
||||
escapeHtml(leg.close_reason || "") +
|
||||
"</td></tr>"
|
||||
);
|
||||
})
|
||||
@@ -594,7 +829,7 @@
|
||||
|
||||
function hideTrade(tradeId) {
|
||||
if (!tradeId) return;
|
||||
if (!confirm("从复盘列表删除并隐藏?刷新后也不会再出现.")) return;
|
||||
if (!confirm("从待复盘列表删除并隐藏?刷新后也不会再出现.")) return;
|
||||
fetch("/api/options/review/trades/" + tradeId, {
|
||||
method: "DELETE",
|
||||
credentials: "same-origin",
|
||||
@@ -618,7 +853,7 @@
|
||||
function saveEntry() {
|
||||
var tradeId = Number(($("or-trade-id") || {}).value || 0);
|
||||
if (!tradeId) {
|
||||
alert("请先在下方列表点选一笔本地记录");
|
||||
alert("请先点击交易记录中的「复盘」");
|
||||
return;
|
||||
}
|
||||
var strategy = (($("or-f-strategy") || {}).value || "").trim();
|
||||
@@ -654,7 +889,9 @@
|
||||
return;
|
||||
}
|
||||
($("or-save-status") || {}).textContent = "已保存";
|
||||
hideJournalForm();
|
||||
reloadAll();
|
||||
openDetail(tradeId);
|
||||
})
|
||||
.catch(function () {
|
||||
($("or-save-status") || {}).textContent = "保存失败";
|
||||
@@ -664,7 +901,7 @@
|
||||
function deleteEntry() {
|
||||
var tradeId = Number(($("or-trade-id") || {}).value || 0);
|
||||
if (!tradeId) return;
|
||||
if (!confirm("删除该条复盘内容与图片?")) return;
|
||||
if (!confirm("删除该条复盘内容与图片?交易记录会回到待复盘列表.")) return;
|
||||
fetch("/api/options/review/entry/" + tradeId, {
|
||||
method: "DELETE",
|
||||
credentials: "same-origin",
|
||||
@@ -674,6 +911,7 @@
|
||||
})
|
||||
.then(function () {
|
||||
hideJournalForm();
|
||||
hideDetail();
|
||||
reloadAll();
|
||||
});
|
||||
}
|
||||
@@ -689,18 +927,56 @@
|
||||
var saveBtn = $("or-save-btn");
|
||||
var clearBtn = $("or-clear-btn");
|
||||
var delBtn = $("or-del-btn");
|
||||
var prevBtn = $("or-trades-prev");
|
||||
var nextBtn = $("or-trades-next");
|
||||
var detailClose = $("or-detail-close-btn");
|
||||
var detailEdit = $("or-detail-edit-btn");
|
||||
if (reloadBtn) reloadBtn.addEventListener("click", reloadAll);
|
||||
if (saveBtn) saveBtn.addEventListener("click", saveEntry);
|
||||
if (clearBtn) clearBtn.addEventListener("click", hideJournalForm);
|
||||
if (delBtn) delBtn.addEventListener("click", deleteEntry);
|
||||
["or-filter-uly", "or-filter-opt", "or-filter-reviewed", "or-include-hedge-legs"].forEach(
|
||||
function (id) {
|
||||
var el = $(id);
|
||||
if (el) el.addEventListener("change", reloadAll);
|
||||
if (prevBtn) {
|
||||
prevBtn.addEventListener("click", function () {
|
||||
if (tradesPage <= 0) return;
|
||||
tradesPage -= 1;
|
||||
loadTrades();
|
||||
});
|
||||
}
|
||||
if (nextBtn) {
|
||||
nextBtn.addEventListener("click", function () {
|
||||
if (!tradesHasMore) return;
|
||||
tradesPage += 1;
|
||||
loadTrades();
|
||||
});
|
||||
}
|
||||
if (detailClose) detailClose.addEventListener("click", hideDetail);
|
||||
if (detailEdit) {
|
||||
detailEdit.addEventListener("click", function () {
|
||||
var id = Number(detailEdit.getAttribute("data-id") || 0);
|
||||
if (id) openJournalForm(id);
|
||||
});
|
||||
}
|
||||
["or-filter-uly", "or-filter-opt", "or-include-hedge-legs"].forEach(function (id) {
|
||||
var el = $(id);
|
||||
if (el) {
|
||||
el.addEventListener("change", function () {
|
||||
tradesPage = 0;
|
||||
reloadAll();
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
["or-filter-strategy", "or-filter-from", "or-filter-to"].forEach(function (id) {
|
||||
var el = $(id);
|
||||
if (el) {
|
||||
el.addEventListener("change", function () {
|
||||
tradesPage = 0;
|
||||
reloadAll();
|
||||
});
|
||||
}
|
||||
});
|
||||
bindUploadSlots();
|
||||
hideJournalForm();
|
||||
hideDetail();
|
||||
setActiveTab("option_spot");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user