From 0bd393ed6af05ab7565aa8e878408f00a5538f56 Mon Sep 17 00:00:00 2001 From: Lxy Date: Wed, 8 Jul 2026 23:14:51 +0800 Subject: [PATCH] =?UTF-8?q?tweak:=20=E5=B0=86=E5=AF=BC=E5=85=A5=E3=80=81?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E5=AF=BC=E5=85=A5=E3=80=81=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=BD=93=E6=97=A5=E7=AD=89=E5=8A=9F=E8=83=BD=E7=8B=AC=E7=AB=8B?= =?UTF-8?q?=E5=88=B0=E6=95=B0=E6=8D=AE=E7=AE=A1=E7=90=86=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/static/futures_analysis.html | 77 +++++++++++++++++++++++++------ app/static/futures_analysis.js | 54 +++++++++++++++++++--- data/futures_analysis.db | Bin 13225984 -> 13225984 bytes 3 files changed, 112 insertions(+), 19 deletions(-) diff --git a/app/static/futures_analysis.html b/app/static/futures_analysis.html index e36e665..4102440 100644 --- a/app/static/futures_analysis.html +++ b/app/static/futures_analysis.html @@ -594,6 +594,18 @@ .tr-tab-panel { display: none; } .tr-tab-panel.active { display: block; } + /* 数据管理 Tab 样式 */ + .tr-data-management { background: var(--bg-card); border-radius: var(--radius-card); padding: 32px; box-shadow: var(--shadow-sm); } + .tr-section-title { font-size: 16px; font-weight: 600; color: var(--text-primary); margin-bottom: 16px; padding-bottom: 8px; border-bottom: 1px solid rgba(0,0,0,0.05); } + .tr-import-section { display: flex; gap: 12px; align-items: center; } + .tr-data-operations { display: flex; flex-direction: column; gap: 16px; } + .tr-operation-item { display: flex; align-items: center; gap: 12px; } + .tr-operation-item label { font-size: 14px; color: var(--text-secondary); min-width: 120px; } + .tr-data-overview { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; } + .tr-overview-card { background: #F5F5F7; border-radius: 12px; padding: 20px; text-align: center; } + .tr-overview-label { font-size: 12px; color: var(--text-tertiary); margin-bottom: 8px; font-weight: 500; } + .tr-overview-value { font-size: 20px; font-weight: 700; color: var(--text-primary); } + /* 交易反思 - 日期导航 */ .tr-refl-datebar { display: flex; align-items: center; justify-content: center; gap: 16px; margin-bottom: 24px; } .tr-refl-datebtn { width: 36px; height: 36px; border-radius: 50%; border: none; background: #fff; color: var(--text-secondary); cursor: pointer; box-shadow: var(--shadow-sm); transition: all 0.2s; font-size: 16px; } @@ -1112,15 +1124,16 @@
+
- -
- -
-
+ +
+
+
结算单导入
+
+
+ +
数据操作
+
+
+ + + +
+
+ + +
+
+ +
数据概览
+
+
+
总交易记录
+
-
+
+
+
导入批次
+
-
+
+
+
最早日期
+
-
+
+
+
最新日期
+
-
+
+
+
+
+ + +
+ +
+
~
-
- - -
diff --git a/app/static/futures_analysis.js b/app/static/futures_analysis.js index 5e36463..5d0257a 100644 --- a/app/static/futures_analysis.js +++ b/app/static/futures_analysis.js @@ -651,6 +651,7 @@ function trSwitchSubtab(tab) { panel.classList.toggle('active', panel.id === 'tr-tab-' + tab); }); if (tab === 'experience') trExpLoad(); + if (tab === 'data') trLoadDataOverview(); } function trSwitchToReflection(date) { @@ -2328,6 +2329,7 @@ async function trHandleFileImport(e) { if (json.success) { trShowImportResult(json.message, json.skipped_details || []); trLoadAllData(); + trLoadDataOverview(); } else { alert('导入失败: ' + (json.message || '未知错误')); } @@ -2402,7 +2404,10 @@ async function trHandleBatchImport(e) { const json = await res.json(); if (json.success) { trShowBatchImportResult(json); - if (json.data.total_futures > 0 || json.data.total_options > 0) trLoadAllData(); + if (json.data.total_futures > 0 || json.data.total_options > 0) { + trLoadAllData(); + trLoadDataOverview(); + } } else { alert('批量导入失败: ' + (json.message || '未知错误')); } @@ -2499,11 +2504,8 @@ function trCloseBatchModal() { // ===== 删除当日 ===== async function trDeleteByDate() { - const startDate = document.getElementById('tr-start-date').value; - const endDate = document.getElementById('tr-end-date').value; - if (!startDate || !endDate) { alert('请先选择要删除的日期范围'); return; } - if (startDate !== endDate) { alert('删除功能仅支持单个日期,请确保开始日期和结束日期相同'); return; } - const tradeDate = startDate; + const tradeDate = document.getElementById('tr-delete-date-input').value; + if (!tradeDate) { alert('请先选择要删除的日期'); return; } try { const queryRes = await fetch(`${TR_API_BASE}/records?start_date=${tradeDate}&end_date=${tradeDate}&page=1&page_size=1`); @@ -2518,12 +2520,52 @@ async function trDeleteByDate() { if (json.success) { alert(`✅ ${json.message}`); trLoadAllData(); + trLoadDataOverview(); } else { alert(json.message || '删除失败'); } } catch (e) { alert('删除失败: ' + e.message); } } +// ===== 数据概览 ===== +async function trLoadDataOverview() { + try { + // 获取总记录数和日期范围 + const res = await fetch(`${TR_API_BASE}/statistics`); + const json = await res.json(); + if (json.success && json.data) { + document.getElementById('tr-total-records').textContent = json.data.total_trades || 0; + document.getElementById('tr-total-batches').textContent = json.data.trading_days || 0; + } + + // 获取批次信息 + const batchRes = await fetch(`${TR_API_BASE}/batches`); + const batchJson = await batchRes.json(); + if (batchJson.success && batchJson.data && batchJson.data.length > 0) { + document.getElementById('tr-total-batches').textContent = batchJson.data.length; + // 获取最早和最新日期 + const dates = batchJson.data.map(b => b.trade_dates).filter(d => d); + if (dates.length > 0) { + const allDates = []; + dates.forEach(d => { + const parts = d.split(' ~ '); + parts.forEach(p => { + const date = p.trim(); + if (date) allDates.push(date); + }); + }); + if (allDates.length > 0) { + allDates.sort(); + document.getElementById('tr-earliest-date').textContent = allDates[0]; + document.getElementById('tr-latest-date').textContent = allDates[allDates.length - 1]; + } + } + } + } catch (e) { + console.error('加载数据概览失败:', e); + } +} + function formatNumber(num) { if (num === 0 || num === undefined || num === null) return '--'; return num.toLocaleString('zh-CN', { minimumFractionDigits: 0, maximumFractionDigits: 2 }); diff --git a/data/futures_analysis.db b/data/futures_analysis.db index 922684f85ee6010c1dd83a417e6da2c9d122affb..e04fd3157260fe557066ef3151980b6f70ca5302 100644 GIT binary patch delta 3964 zcmd5HOxm-}!#$J7>ya*aXK7tQHNAM#M1d0$q2qKI_7>`hZa2dkq5GEi@M3{tdIl^RwDF{;$u0WWE zP>4{3FdgAagsTu{AY6?w6JZv@Y=mnN<{*3?p%|eA;R^@`LMeiYP=+uUp&Y?N2qA&u2Zt286F7#1X!Ra4SMR!bXHm z2%8bUj_?hH+YlNM8WFZ2+>Y=~gl{2y8{rOwtq6A_dpXsW1XQ)S zXG`C-fFmy#-9f{tx^~Q<{Eu7v<|N}=`wnZKe0u~fBJgVvu zpB`$VTG(L!{5NnLp9VcUQmgc2q2UZW__o?j`TUyw>0c*2yAKj+dP;H)t{&h7uem2Y>et}8UxByC=;J&3xlbYxng zIx}P#9z}8V*+C~9{77T^xDY{SAGOzD@_|DVm}^^m*D%yJ!a;B*m8& zbm0Xgh8kmH^`g;`7%f0A@~s#{BtCX>@98lIc!9fHn+lSF)}~{so#ww%dB-D7_1RlN z1{L}a{hhoG$K^d}qdV#CbRAtnE9h)Gf##7x-|OLyZg8`^G26KJTbdr;dg- zqXno_-RA!Q-K`J5QEME*fV+q~OvAK_jq+kMQs?A@)#=A#oQhnRSniAR{|V&YLI9%JHhCZ1s8NhZF} zL^l&hn0ShbrkQ)(`QU&!3!9$hzB#Q^mu}Zd;SO{Qq>-dTORC z8uPU)^ayRI6RAq>AzMkDEYlOdb95IOB-fG>GKJ*(-=*jLZ|Y9{Hs7oMU;1C6ulkSr z&T}h}ny&j!_>TD6>3RKa{c658kecY!3*^xRd^|KI6->l}?qHFl_Qq_cWlrZml&Xv} zf8|I_Wk!(|HIugXsEUlTpk`RHq8E>{A{k}*(vg_3OmkW!3;WPKRwyZ#b=FlGBa4(w zCAMpCBi%^X(>3HtQcnkEW$vKM>0((st7(WD|c)9G|FEg%g%T$n1<$!fBU zETaD;zaTsL+CsT;(lq?uX>?SpuAtm^ENd=!Rkk;OWuASNuGjC5z>U#N^SU0ZTv)kR=C;1~uA^Bs;S0qnKo|gQHI zOWr4WucG+=D*4v%b6w?X-Qw;9ml=sy*uh@UhvZT#R9YUlG7C@2J^eZF-(Uw(&Hw-a delta 44013 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