diff --git a/manual_trading_hub/static/app.css b/manual_trading_hub/static/app.css index a48a6be..427fa18 100644 --- a/manual_trading_hub/static/app.css +++ b/manual_trading_hub/static/app.css @@ -5532,37 +5532,49 @@ body.funds-fullscreen-open { } .archive-quotes-list { flex: 1 1 auto; - min-height: 420px; + min-height: 160px; overflow: auto; display: flex; flex-direction: column; gap: 8px; } -.archive-quote-card { +.archive-quote-item { + display: grid; + grid-template-columns: auto 1fr; + gap: 8px; + align-items: center; + width: 100%; + padding: 8px 10px; border: 1px solid var(--border-soft); border-radius: 8px; background: var(--inset-surface); - overflow: hidden; -} -.archive-quote-summary { - display: grid; - grid-template-columns: auto 1fr auto; - gap: 8px; - align-items: center; - padding: 8px 10px; + color: inherit; + font: inherit; + text-align: left; cursor: pointer; - list-style: none; } -.archive-quote-open-hint { - font-size: 0.7rem; - color: var(--accent); - white-space: nowrap; +.archive-quote-item:hover { + border-color: color-mix(in srgb, var(--accent) 40%, var(--border-soft)); } -.archive-quote-card[open] .archive-quote-open-hint { - color: var(--muted); +.archive-quote-item.is-selected { + border-color: var(--accent); + background: color-mix(in srgb, var(--accent) 12%, var(--inset-surface)); } -.archive-quote-summary::-webkit-details-marker { - display: none; +.archive-quote-detail { + flex: 0 0 auto; + display: flex; + flex-direction: column; + gap: 8px; + padding-top: 10px; + border-top: 1px solid var(--border-soft); + min-height: 140px; + max-height: 42vh; +} +.archive-quote-detail .archive-quote-full { + flex: 1 1 auto; + min-height: 96px; + max-height: 34vh; + overflow: auto; } .archive-quote-date { font-weight: 600; @@ -5577,12 +5589,6 @@ body.funds-fullscreen-open { text-overflow: ellipsis; white-space: nowrap; } -.archive-quote-body { - padding: 0 10px 10px; - display: flex; - flex-direction: column; - gap: 8px; -} .archive-quote-full { padding: 10px 12px; border-radius: 8px; @@ -5595,20 +5601,6 @@ body.funds-fullscreen-open { word-break: break-word; max-height: none; } -.archive-quote-edit { - width: 100%; - min-height: 160px; - padding: 8px 10px; - border-radius: 8px; - border: 1px solid var(--border-soft); - background: var(--panel); - color: var(--text); - font-family: var(--font); - font-size: 0.8rem; - resize: vertical; - line-height: 1.55; - white-space: pre-wrap; -} .archive-quote-actions { display: flex; gap: 8px; @@ -5943,7 +5935,10 @@ body.funds-fullscreen-open { max-height: none; } .archive-quotes-list { - min-height: 220px; + min-height: 120px; + } + .archive-quote-detail { + max-height: 36vh; } } diff --git a/manual_trading_hub/static/archive.js b/manual_trading_hub/static/archive.js index 3dd709e..20e1b65 100644 --- a/manual_trading_hub/static/archive.js +++ b/manual_trading_hub/static/archive.js @@ -25,6 +25,11 @@ const elQuoteForm = document.getElementById("archive-quote-form"); const elQuoteDate = document.getElementById("archive-quote-date"); const elQuoteContent = document.getElementById("archive-quote-content"); + const elQuoteSubmit = document.getElementById("archive-quote-submit"); + const elQuoteDetail = document.getElementById("archive-quote-detail"); + const elQuoteDetailFull = document.getElementById("archive-quote-detail-full"); + const elQuoteEditBtn = document.getElementById("archive-quote-edit-btn"); + const elQuoteDelBtn = document.getElementById("archive-quote-del-btn"); const elChartSection = document.getElementById("archive-chart-section"); const elChartTitle = document.getElementById("archive-chart-title"); const elTfTabs = document.getElementById("archive-tf-tabs"); @@ -49,6 +54,8 @@ let meta = null; let quotes = []; + let selectedQuoteId = null; + let editingQuoteId = null; let dailyTrades = []; let dailyStats = { open_count: 0, by_exchange: {} }; let periodMode = "today"; @@ -480,20 +487,57 @@ return s.length > 36 ? s.slice(0, 36) + "…" : s; } - function quoteEditRows(text) { - const t = String(text || ""); - const lines = t.split(/\n/).length; - const wrapLines = Math.ceil(t.length / 26); - return Math.min(32, Math.max(8, lines, wrapLines)); + function findQuote(id) { + if (id == null || id === "") return null; + return ( + quotes.find(function (q) { + return String(q.id) === String(id); + }) || null + ); } - function resizeQuoteTextarea(ta) { - if (!ta) return; - ta.style.height = "auto"; - const lines = String(ta.value || "").split("\n").length; - const wrapLines = Math.ceil(String(ta.value || "").length / 26); - ta.rows = Math.min(32, Math.max(8, lines, wrapLines)); - ta.style.height = Math.max(ta.scrollHeight, 160) + "px"; + function updateQuoteSubmitBtn() { + if (!elQuoteSubmit) return; + elQuoteSubmit.textContent = editingQuoteId ? "修改保存" : "添加语录"; + } + + function resetQuoteForm() { + editingQuoteId = null; + if (elQuoteContent) elQuoteContent.value = ""; + updateQuoteSubmitBtn(); + } + + function startEditQuote() { + const q = findQuote(selectedQuoteId); + if (!q) return; + editingQuoteId = q.id; + if (elQuoteDate) elQuoteDate.value = q.quote_date || ""; + if (elQuoteContent) { + elQuoteContent.value = q.content || ""; + elQuoteContent.focus(); + } + updateQuoteSubmitBtn(); + } + + function selectQuote(id) { + if (editingQuoteId != null && String(id) !== String(editingQuoteId)) { + resetQuoteForm(); + } + selectedQuoteId = id; + renderQuotes(); + renderQuoteDetail(); + } + + function renderQuoteDetail() { + if (!elQuoteDetail) return; + const q = findQuote(selectedQuoteId); + if (!q) { + elQuoteDetail.hidden = true; + if (elQuoteDetailFull) elQuoteDetailFull.textContent = ""; + return; + } + elQuoteDetail.hidden = false; + if (elQuoteDetailFull) elQuoteDetailFull.textContent = q.content || "(空)"; } function renderQuotes() { @@ -503,79 +547,58 @@ } if (!quotes.length) { elQuotesList.innerHTML = '
暂无复盘语录,可在上方添加。
'; + if (elQuoteDetail) elQuoteDetail.hidden = true; return; } elQuotesList.innerHTML = quotes .map(function (q) { + const selected = String(q.id) === String(selectedQuoteId); return ( - '