Add archive tabs for trades vs review quotes.
Switch hub 内照明心 to a single-column tab layout and auto-show that day's closed trades under the quote form for AI review context. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -165,7 +165,7 @@ def build_chat_user_prompt(
|
|||||||
|
|
||||||
|
|
||||||
ARCHIVE_QUOTE_REVIEW_INSTRUCTION = """
|
ARCHIVE_QUOTE_REVIEW_INSTRUCTION = """
|
||||||
【任务】用户从内照明心提交了一条复盘语录,并附上该交易日的档案交易记录(仅供你分析,用户界面不展示明细).
|
【任务】用户从内照明心提交了一条复盘语录,并附上该交易日的档案交易记录(界面「复盘语录」下方也会展示当日已平仓明细).
|
||||||
请结合语录与交易记录:
|
请结合语录与交易记录:
|
||||||
1) 帮他核对自述与操作事实是否一致;
|
1) 帮他核对自述与操作事实是否一致;
|
||||||
2) 指出心态,纪律,执行上的偏差点(若有);
|
2) 指出心态,纪律,执行上的偏差点(若有);
|
||||||
@@ -236,7 +236,7 @@ def build_archive_quote_review_prompt(
|
|||||||
parts = [
|
parts = [
|
||||||
f"【复盘交易日】{quote_date}",
|
f"【复盘交易日】{quote_date}",
|
||||||
ARCHIVE_QUOTE_REVIEW_INSTRUCTION,
|
ARCHIVE_QUOTE_REVIEW_INSTRUCTION,
|
||||||
"【该日交易记录(内照明心档案,用户不可见此段)】",
|
"【该日交易记录(内照明心档案,与界面「当日已平仓」一致)】",
|
||||||
(archive_trades_text or "(该日无交易记录)").strip(),
|
(archive_trades_text or "(该日无交易记录)").strip(),
|
||||||
"【用户复盘语录(对话框已展示,请优先回应)】",
|
"【用户复盘语录(对话框已展示,请优先回应)】",
|
||||||
user_message.strip(),
|
user_message.strip(),
|
||||||
|
|||||||
@@ -7956,10 +7956,30 @@ body.funds-fullscreen-open {
|
|||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
.archive-layout {
|
.archive-layout {
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: minmax(240px, 300px) minmax(0, 1fr);
|
flex-direction: column;
|
||||||
gap: 14px;
|
gap: 12px;
|
||||||
align-items: start;
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
.archive-content-tabs {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.archive-content-tab {
|
||||||
|
border: 1px solid var(--border-soft);
|
||||||
|
background: transparent;
|
||||||
|
color: inherit;
|
||||||
|
padding: 7px 14px;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: var(--font);
|
||||||
|
font-size: 0.84rem;
|
||||||
|
}
|
||||||
|
.archive-content-tab.is-active {
|
||||||
|
background: rgba(59, 130, 246, 0.22);
|
||||||
|
border-color: rgba(59, 130, 246, 0.55);
|
||||||
|
color: var(--text);
|
||||||
}
|
}
|
||||||
.archive-quotes-panel,
|
.archive-quotes-panel,
|
||||||
.archive-main-panel {
|
.archive-main-panel {
|
||||||
@@ -7968,13 +7988,23 @@ body.funds-fullscreen-open {
|
|||||||
border-radius: var(--radius);
|
border-radius: var(--radius);
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
.archive-quotes-panel {
|
.archive-tab-panel {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.archive-tab-panel.is-active {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.archive-quotes-panel.is-active {
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
.archive-main-panel.is-active {
|
||||||
|
gap: 10px;
|
||||||
|
padding: 12px;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
.archive-panel-head {
|
.archive-panel-head {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -8009,6 +8039,46 @@ body.funds-fullscreen-open {
|
|||||||
.archive-quote-form textarea {
|
.archive-quote-form textarea {
|
||||||
min-height: 110px;
|
min-height: 110px;
|
||||||
}
|
}
|
||||||
|
.archive-quote-day-trades {
|
||||||
|
border: 1px solid var(--border-soft);
|
||||||
|
border-radius: 8px;
|
||||||
|
background: var(--inset-surface);
|
||||||
|
padding: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.archive-quote-day-trades-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.archive-quote-day-trades-head h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.84rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.archive-quote-day-trades-body {
|
||||||
|
overflow: auto;
|
||||||
|
max-height: min(280px, 40vh);
|
||||||
|
}
|
||||||
|
.archive-quote-day-trades-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
}
|
||||||
|
.archive-quote-day-trades-table th,
|
||||||
|
.archive-quote-day-trades-table td {
|
||||||
|
padding: 6px 8px;
|
||||||
|
border-bottom: 1px solid var(--border-soft);
|
||||||
|
text-align: left;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.archive-quote-day-trades-table th {
|
||||||
|
color: var(--muted);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
.archive-quotes-list {
|
.archive-quotes-list {
|
||||||
flex: 0 1 auto;
|
flex: 0 1 auto;
|
||||||
max-height: min(420px, 50vh);
|
max-height: min(420px, 50vh);
|
||||||
@@ -8101,14 +8171,6 @@ body.funds-fullscreen-open {
|
|||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
border-color: color-mix(in srgb, var(--accent) 35%, var(--border-soft));
|
border-color: color-mix(in srgb, var(--accent) 35%, var(--border-soft));
|
||||||
}
|
}
|
||||||
.archive-main-panel {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
padding: 12px;
|
|
||||||
min-height: 100%;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
.archive-period-bar {
|
.archive-period-bar {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
@@ -8841,19 +8903,13 @@ body.funds-fullscreen-open {
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
#page-archive .archive-quotes-panel {
|
#page-archive .archive-quotes-panel,
|
||||||
order: 1;
|
#page-archive .archive-main-panel {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
max-height: none;
|
max-height: none;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
#page-archive .archive-main-panel {
|
|
||||||
order: 2;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
min-height: 0;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
#page-archive .archive-stats-card {
|
#page-archive .archive-stats-card {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
@@ -8861,6 +8917,9 @@ body.funds-fullscreen-open {
|
|||||||
min-height: 120px;
|
min-height: 120px;
|
||||||
max-height: 42vh;
|
max-height: 42vh;
|
||||||
}
|
}
|
||||||
|
#page-archive .archive-quote-day-trades-body {
|
||||||
|
max-height: 32vh;
|
||||||
|
}
|
||||||
#page-archive .archive-stats-table th,
|
#page-archive .archive-stats-table th,
|
||||||
#page-archive .archive-stats-table td {
|
#page-archive .archive-stats-table td {
|
||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
|
|||||||
@@ -34,6 +34,11 @@
|
|||||||
const elQuoteDate = document.getElementById("archive-quote-date");
|
const elQuoteDate = document.getElementById("archive-quote-date");
|
||||||
const elQuoteContent = document.getElementById("archive-quote-content");
|
const elQuoteContent = document.getElementById("archive-quote-content");
|
||||||
const elQuoteSubmit = document.getElementById("archive-quote-submit");
|
const elQuoteSubmit = document.getElementById("archive-quote-submit");
|
||||||
|
const elContentTabs = document.getElementById("archive-content-tabs");
|
||||||
|
const elPanelTrades = document.getElementById("archive-panel-trades");
|
||||||
|
const elPanelQuotes = document.getElementById("archive-panel-quotes");
|
||||||
|
const elQuoteDayTradesMeta = document.getElementById("archive-quote-day-trades-meta");
|
||||||
|
const elQuoteDayTradesBody = document.getElementById("archive-quote-day-trades-body");
|
||||||
const elChartSection = document.getElementById("archive-chart-section");
|
const elChartSection = document.getElementById("archive-chart-section");
|
||||||
const elChartTitle = document.getElementById("archive-chart-title");
|
const elChartTitle = document.getElementById("archive-chart-title");
|
||||||
const elTfTabs = document.getElementById("archive-tf-tabs");
|
const elTfTabs = document.getElementById("archive-tf-tabs");
|
||||||
@@ -65,6 +70,10 @@
|
|||||||
let quotes = [];
|
let quotes = [];
|
||||||
let selectedQuoteId = null;
|
let selectedQuoteId = null;
|
||||||
let editingQuoteId = null;
|
let editingQuoteId = null;
|
||||||
|
let archiveContentTab = "trades";
|
||||||
|
let quoteDayTrades = [];
|
||||||
|
let quoteDayTradesDay = "";
|
||||||
|
let quoteDayTradesReq = 0;
|
||||||
let dailyTrades = [];
|
let dailyTrades = [];
|
||||||
let tradesPage = 0;
|
let tradesPage = 0;
|
||||||
let dailyStats = { open_count: 0, by_exchange: {} };
|
let dailyStats = { open_count: 0, by_exchange: {} };
|
||||||
@@ -547,9 +556,11 @@
|
|||||||
selectedCalendarDay = day;
|
selectedCalendarDay = day;
|
||||||
setPeriodMode("today");
|
setPeriodMode("today");
|
||||||
if (elTradingDay) elTradingDay.value = day;
|
if (elTradingDay) elTradingDay.value = day;
|
||||||
|
if (elQuoteDate) elQuoteDate.value = day;
|
||||||
if (elFilterSick) elFilterSick.checked = false;
|
if (elFilterSick) elFilterSick.checked = false;
|
||||||
syncPeriodUI();
|
syncPeriodUI();
|
||||||
void loadDailyTrades();
|
void loadDailyTrades();
|
||||||
|
if (archiveContentTab === "quotes") void loadQuoteDayTrades();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
calendarWidget.ensureMonth(calendarRefDate());
|
calendarWidget.ensureMonth(calendarRefDate());
|
||||||
@@ -943,6 +954,146 @@
|
|||||||
elQuoteSubmit.textContent = editingQuoteId ? "修改保存" : "添加语录";
|
elQuoteSubmit.textContent = editingQuoteId ? "修改保存" : "添加语录";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function syncQuoteDateFromTradingDay(force) {
|
||||||
|
if (!elQuoteDate) return;
|
||||||
|
const day =
|
||||||
|
(elTradingDay && elTradingDay.value) ||
|
||||||
|
selectedCalendarDay ||
|
||||||
|
tradingDay ||
|
||||||
|
"";
|
||||||
|
if (!day) return;
|
||||||
|
if (force || !elQuoteDate.value) {
|
||||||
|
elQuoteDate.value = day;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setArchiveContentTab(tab) {
|
||||||
|
const next = tab === "quotes" ? "quotes" : "trades";
|
||||||
|
archiveContentTab = next;
|
||||||
|
const showQuotes = next === "quotes";
|
||||||
|
if (elContentTabs) {
|
||||||
|
elContentTabs.querySelectorAll(".archive-content-tab").forEach(function (btn) {
|
||||||
|
const on = btn.getAttribute("data-archive-tab") === next;
|
||||||
|
btn.classList.toggle("is-active", on);
|
||||||
|
btn.setAttribute("aria-selected", on ? "true" : "false");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (elPanelTrades) {
|
||||||
|
elPanelTrades.classList.toggle("is-active", !showQuotes);
|
||||||
|
elPanelTrades.hidden = showQuotes;
|
||||||
|
}
|
||||||
|
if (elPanelQuotes) {
|
||||||
|
elPanelQuotes.classList.toggle("is-active", showQuotes);
|
||||||
|
elPanelQuotes.hidden = !showQuotes;
|
||||||
|
}
|
||||||
|
if (showQuotes) {
|
||||||
|
syncQuoteDateFromTradingDay(false);
|
||||||
|
void loadQuoteDayTrades();
|
||||||
|
} else {
|
||||||
|
requestAnimationFrame(syncTradesLayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function quoteTagLabel(t) {
|
||||||
|
if (!t) return "—";
|
||||||
|
if (t.behavior_tag_from_journal || t.behavior_tag === "sick") return "犯病";
|
||||||
|
if (t.behavior_tag === "emotion") return "情绪";
|
||||||
|
return "—";
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderQuoteDayTrades() {
|
||||||
|
if (!elQuoteDayTradesBody) return;
|
||||||
|
const day = quoteDayTradesDay || (elQuoteDate && elQuoteDate.value) || "";
|
||||||
|
if (elQuoteDayTradesMeta) {
|
||||||
|
elQuoteDayTradesMeta.textContent = day
|
||||||
|
? day + " · " + quoteDayTrades.length + " 笔"
|
||||||
|
: "";
|
||||||
|
}
|
||||||
|
if (!day) {
|
||||||
|
elQuoteDayTradesBody.innerHTML =
|
||||||
|
'<p class="archive-empty">选择日期后自动带上该日已平仓记录.</p>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!quoteDayTrades.length) {
|
||||||
|
elQuoteDayTradesBody.innerHTML =
|
||||||
|
'<p class="archive-empty">该日暂无已平仓记录.</p>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
elQuoteDayTradesBody.innerHTML =
|
||||||
|
'<table class="archive-quote-day-trades-table"><thead><tr>' +
|
||||||
|
"<th>交易所</th><th>合约</th><th>方向</th><th>开仓</th><th>平仓</th><th>盈亏</th><th>标签</th>" +
|
||||||
|
"</tr></thead><tbody>" +
|
||||||
|
quoteDayTrades
|
||||||
|
.map(function (t) {
|
||||||
|
return (
|
||||||
|
"<tr>" +
|
||||||
|
"<td>" +
|
||||||
|
esc(tradeRowExchange(t)) +
|
||||||
|
"</td>" +
|
||||||
|
"<td>" +
|
||||||
|
esc(t.symbol || "—") +
|
||||||
|
"</td>" +
|
||||||
|
"<td>" +
|
||||||
|
esc(t.direction || "—") +
|
||||||
|
"</td>" +
|
||||||
|
'<td class="archive-dt">' +
|
||||||
|
fmtDt(t.opened_at) +
|
||||||
|
"</td>" +
|
||||||
|
'<td class="archive-dt">' +
|
||||||
|
fmtDt(t.closed_at) +
|
||||||
|
"</td>" +
|
||||||
|
'<td class="' +
|
||||||
|
pnlClass(t.pnl_amount) +
|
||||||
|
'">' +
|
||||||
|
fmtPnl(t.pnl_amount) +
|
||||||
|
"</td>" +
|
||||||
|
"<td>" +
|
||||||
|
esc(quoteTagLabel(t)) +
|
||||||
|
"</td></tr>"
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.join("") +
|
||||||
|
"</tbody></table>";
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadQuoteDayTrades() {
|
||||||
|
if (!elQuoteDayTradesBody) return;
|
||||||
|
const day = elQuoteDate && String(elQuoteDate.value || "").trim();
|
||||||
|
if (!day) {
|
||||||
|
quoteDayTrades = [];
|
||||||
|
quoteDayTradesDay = "";
|
||||||
|
renderQuoteDayTrades();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const req = ++quoteDayTradesReq;
|
||||||
|
const q = new URLSearchParams();
|
||||||
|
q.set("period", "today");
|
||||||
|
q.set("trading_day", day);
|
||||||
|
elQuoteDayTradesBody.innerHTML = '<p class="archive-empty">加载当日已平仓…</p>';
|
||||||
|
if (elQuoteDayTradesMeta) elQuoteDayTradesMeta.textContent = day;
|
||||||
|
try {
|
||||||
|
const r = await apiFetch("/api/archive/daily-trades?" + q.toString());
|
||||||
|
const j = await r.json();
|
||||||
|
if (req !== quoteDayTradesReq) return;
|
||||||
|
if (!r.ok) {
|
||||||
|
quoteDayTrades = [];
|
||||||
|
quoteDayTradesDay = day;
|
||||||
|
elQuoteDayTradesBody.innerHTML =
|
||||||
|
'<p class="archive-empty">' + esc(j.detail || "加载失败") + "</p>";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
quoteDayTrades = j.trades || [];
|
||||||
|
quoteDayTradesDay = day;
|
||||||
|
renderQuoteDayTrades();
|
||||||
|
} catch (_) {
|
||||||
|
if (req !== quoteDayTradesReq) return;
|
||||||
|
quoteDayTrades = [];
|
||||||
|
quoteDayTradesDay = day;
|
||||||
|
elQuoteDayTradesBody.innerHTML =
|
||||||
|
'<p class="archive-empty">加载失败</p>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function resetQuoteForm() {
|
function resetQuoteForm() {
|
||||||
editingQuoteId = null;
|
editingQuoteId = null;
|
||||||
if (elQuoteContent) elQuoteContent.value = "";
|
if (elQuoteContent) elQuoteContent.value = "";
|
||||||
@@ -959,6 +1110,7 @@
|
|||||||
elQuoteContent.focus();
|
elQuoteContent.focus();
|
||||||
}
|
}
|
||||||
updateQuoteSubmitBtn();
|
updateQuoteSubmitBtn();
|
||||||
|
void loadQuoteDayTrades();
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectQuote(id) {
|
function selectQuote(id) {
|
||||||
@@ -1839,6 +1991,7 @@
|
|||||||
renderStats();
|
renderStats();
|
||||||
renderTrades();
|
renderTrades();
|
||||||
void loadCalendar();
|
void loadCalendar();
|
||||||
|
if (archiveContentTab === "quotes") void loadQuoteDayTrades();
|
||||||
setStatus(
|
setStatus(
|
||||||
(periodLabel || tradingDay || "当日") +
|
(periodLabel || tradingDay || "当日") +
|
||||||
" · 列表 " +
|
" · 列表 " +
|
||||||
@@ -1932,7 +2085,12 @@
|
|||||||
loadDailyTrades();
|
loadDailyTrades();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (elTradingDay) elTradingDay.addEventListener("change", loadDailyTrades);
|
if (elTradingDay) {
|
||||||
|
elTradingDay.addEventListener("change", function () {
|
||||||
|
if (elQuoteDate && elTradingDay.value) elQuoteDate.value = elTradingDay.value;
|
||||||
|
void loadDailyTrades();
|
||||||
|
});
|
||||||
|
}
|
||||||
if (elDateFrom) elDateFrom.addEventListener("change", loadDailyTrades);
|
if (elDateFrom) elDateFrom.addEventListener("change", loadDailyTrades);
|
||||||
if (elDateTo) elDateTo.addEventListener("change", loadDailyTrades);
|
if (elDateTo) elDateTo.addEventListener("change", loadDailyTrades);
|
||||||
[elFilterProfit, elFilterLoss, elFilterSick].forEach(function (el) {
|
[elFilterProfit, elFilterLoss, elFilterSick].forEach(function (el) {
|
||||||
@@ -1967,6 +2125,18 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (elQuoteForm) elQuoteForm.addEventListener("submit", submitQuoteForm);
|
if (elQuoteForm) elQuoteForm.addEventListener("submit", submitQuoteForm);
|
||||||
|
if (elQuoteDate) {
|
||||||
|
elQuoteDate.addEventListener("change", function () {
|
||||||
|
void loadQuoteDayTrades();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (elContentTabs) {
|
||||||
|
elContentTabs.addEventListener("click", function (ev) {
|
||||||
|
const btn = ev.target.closest(".archive-content-tab");
|
||||||
|
if (!btn) return;
|
||||||
|
setArchiveContentTab(btn.getAttribute("data-archive-tab") || "trades");
|
||||||
|
});
|
||||||
|
}
|
||||||
if (elTfTabs) {
|
if (elTfTabs) {
|
||||||
elTfTabs.addEventListener("click", function (ev) {
|
elTfTabs.addEventListener("click", function (ev) {
|
||||||
const btn = ev.target.closest(".archive-tf-btn");
|
const btn = ev.target.closest(".archive-tf-btn");
|
||||||
@@ -1999,6 +2169,7 @@
|
|||||||
syncPeriodUI();
|
syncPeriodUI();
|
||||||
syncTradesLayout();
|
syncTradesLayout();
|
||||||
bindEvents();
|
bindEvents();
|
||||||
|
setArchiveContentTab("trades");
|
||||||
inited = true;
|
inited = true;
|
||||||
}
|
}
|
||||||
await loadMeta();
|
await loadMeta();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'" />
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'" />
|
||||||
<noscript><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" /></noscript>
|
<noscript><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" /></noscript>
|
||||||
<link rel="stylesheet" href="/assets/app.css?v=20260717-archive-compact" />
|
<link rel="stylesheet" href="/assets/app.css?v=20260717-archive-tabs" />
|
||||||
<link rel="stylesheet" href="/assets/trade_stats_calendar.css?v=4" />
|
<link rel="stylesheet" href="/assets/trade_stats_calendar.css?v=4" />
|
||||||
<link rel="stylesheet" href="/assets/account_risk_badge.css?v=4" />
|
<link rel="stylesheet" href="/assets/account_risk_badge.css?v=4" />
|
||||||
<script src="/assets/account_risk_badge.js?v=4"></script>
|
<script src="/assets/account_risk_badge.js?v=4"></script>
|
||||||
@@ -489,19 +489,11 @@
|
|||||||
</details>
|
</details>
|
||||||
</section>
|
</section>
|
||||||
<div class="archive-layout">
|
<div class="archive-layout">
|
||||||
<aside class="archive-quotes-panel">
|
<div class="archive-content-tabs" id="archive-content-tabs" role="tablist" aria-label="内照明心分区">
|
||||||
<div class="archive-panel-head">
|
<button type="button" class="archive-content-tab is-active" role="tab" aria-selected="true" data-archive-tab="trades" id="archive-tab-trades">交易记录</button>
|
||||||
<h2>复盘语录</h2>
|
<button type="button" class="archive-content-tab" role="tab" aria-selected="false" data-archive-tab="quotes" id="archive-tab-quotes">复盘语录</button>
|
||||||
<span id="archive-quotes-count" class="archive-panel-meta"></span>
|
|
||||||
</div>
|
</div>
|
||||||
<form id="archive-quote-form" class="archive-quote-form">
|
<main class="archive-main-panel archive-tab-panel is-active" id="archive-panel-trades" role="tabpanel" aria-labelledby="archive-tab-trades">
|
||||||
<input id="archive-quote-date" type="date" required />
|
|
||||||
<textarea id="archive-quote-content" rows="5" placeholder="今日复盘心得…" required></textarea>
|
|
||||||
<button type="submit" id="archive-quote-submit" class="primary">添加语录</button>
|
|
||||||
</form>
|
|
||||||
<div id="archive-quotes-list" class="archive-quotes-list"></div>
|
|
||||||
</aside>
|
|
||||||
<main class="archive-main-panel">
|
|
||||||
<details class="archive-acc-section archive-calendar-section" id="archive-calendar-section" open>
|
<details class="archive-acc-section archive-calendar-section" id="archive-calendar-section" open>
|
||||||
<summary class="archive-acc-summary">交易日历 <span id="archive-cal-summary-sub" class="archive-acc-sub">—</span></summary>
|
<summary class="archive-acc-summary">交易日历 <span id="archive-cal-summary-sub" class="archive-acc-sub">—</span></summary>
|
||||||
<div id="archive-calendar-wrap" class="trade-cal-wrap">
|
<div id="archive-calendar-wrap" class="trade-cal-wrap">
|
||||||
@@ -551,6 +543,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
</main>
|
</main>
|
||||||
|
<aside class="archive-quotes-panel archive-tab-panel" id="archive-panel-quotes" role="tabpanel" aria-labelledby="archive-tab-quotes" hidden>
|
||||||
|
<div class="archive-panel-head">
|
||||||
|
<h2>复盘语录</h2>
|
||||||
|
<span id="archive-quotes-count" class="archive-panel-meta"></span>
|
||||||
|
</div>
|
||||||
|
<form id="archive-quote-form" class="archive-quote-form">
|
||||||
|
<input id="archive-quote-date" type="date" required />
|
||||||
|
<textarea id="archive-quote-content" rows="5" placeholder="今日复盘心得…" required></textarea>
|
||||||
|
<button type="submit" id="archive-quote-submit" class="primary">添加语录</button>
|
||||||
|
</form>
|
||||||
|
<div class="archive-quote-day-trades" id="archive-quote-day-trades">
|
||||||
|
<div class="archive-quote-day-trades-head">
|
||||||
|
<h3>当日已平仓</h3>
|
||||||
|
<span id="archive-quote-day-trades-meta" class="archive-panel-meta"></span>
|
||||||
|
</div>
|
||||||
|
<div id="archive-quote-day-trades-body" class="archive-quote-day-trades-body">
|
||||||
|
<p class="archive-empty">选择日期后自动带上该日已平仓记录.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="archive-quotes-list" class="archive-quotes-list"></div>
|
||||||
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1316,7 +1329,7 @@
|
|||||||
<script src="/assets/plan.js?v=20260614-plan-refresh"></script>
|
<script src="/assets/plan.js?v=20260614-plan-refresh"></script>
|
||||||
<script src="/assets/calculator.js?v=20260715-calc-tabs"></script>
|
<script src="/assets/calculator.js?v=20260715-calc-tabs"></script>
|
||||||
<script src="/assets/trade_stats_calendar.js?v=3"></script>
|
<script src="/assets/trade_stats_calendar.js?v=3"></script>
|
||||||
<script src="/assets/archive.js?v=20260717-trades-pager"></script>
|
<script src="/assets/archive.js?v=20260717-archive-tabs"></script>
|
||||||
<script src="/assets/funds.js?v=20260717-funds-scroll-fix"></script>
|
<script src="/assets/funds.js?v=20260717-funds-scroll-fix"></script>
|
||||||
<script src="/assets/dashboard.js?v=20260708-options-expiry-cd"></script>
|
<script src="/assets/dashboard.js?v=20260708-options-expiry-cd"></script>
|
||||||
<script src="/assets/strategy.js?v=3"></script>
|
<script src="/assets/strategy.js?v=3"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user