From ce7b5fc133853a4cb2c64a19ae5c62c9e7fb8948 Mon Sep 17 00:00:00 2001 From: Lxy Date: Sun, 17 May 2026 22:24:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0json=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/__pycache__/__init__.cpython-311.pyc | Bin 221 -> 159 bytes app/__pycache__/config.cpython-311.pyc | Bin 1553 -> 1491 bytes app/__pycache__/database.cpython-311.pyc | Bin 1327 -> 1265 bytes app/__pycache__/main.cpython-311.pyc | Bin 5530 -> 5468 bytes app/__pycache__/models.cpython-311.pyc | Bin 4581 -> 4519 bytes app/__pycache__/schemas.cpython-311.pyc | Bin 6430 -> 6330 bytes app/api/__pycache__/__init__.cpython-311.pyc | Bin 225 -> 163 bytes app/api/__pycache__/config.cpython-311.pyc | Bin 14820 -> 14758 bytes app/api/__pycache__/data.cpython-311.pyc | Bin 9773 -> 9711 bytes app/api/__pycache__/tasks.cpython-311.pyc | Bin 10445 -> 10383 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 230 -> 168 bytes .../__pycache__/cache.cpython-311.pyc | Bin 11804 -> 11742 bytes .../__pycache__/collector.cpython-311.pyc | Bin 3490 -> 3428 bytes .../__pycache__/scheduler.cpython-311.pyc | Bin 9831 -> 9769 bytes app/static/index.html | 50 ++++++++++++++++++ 15 files changed, 50 insertions(+) diff --git a/app/__pycache__/__init__.cpython-311.pyc b/app/__pycache__/__init__.cpython-311.pyc index 92086fc12541bc2cfb0af41b7afcaa74a56e70f5..5da7f5f3f41a50d113a9c4ee666050a7ac91e017 100644 GIT binary patch delta 65 zcmcc1IG>SsIWI340}$AqXK3L^l&s}|n? delta 106 zcmcc2J&}iZIWI340}!mv;mC^L$jilIlBb_oP@rF)UzDAhmky?j3lfu4i}h1d(-KQ_ zO7x2}5{pvfQxZ!O^$Uvfvr>~w^d}!@k`>iYDosmEEs8J5Ni0drFUkd*v)P_y3L^kB CyCj4F diff --git a/app/__pycache__/database.cpython-311.pyc b/app/__pycache__/database.cpython-311.pyc index 2e3b6db97c8c0f8597d10c729a3b8b31c6a37615..507bc0c55d334c693abcafac693b84698a29bb6a 100644 GIT binary patch delta 68 zcmZ3_^^uczIWI340}$AqxT7FS(OkzPn%w}WeKa2qLt{40O delta 155 zcmey!xt@!6IWI340}xEg;mE4o$a{dPzCb^*pg_MozbHF1FC9!57bGU97VD>^rX`l< zl;{^{Bo?K{rzDmn>K7E{XQd{W=;tODWv7;a#p09mbAUqmMezkWi6v?IMY;M(rDo|4* diff --git a/app/__pycache__/main.cpython-311.pyc b/app/__pycache__/main.cpython-311.pyc index 13e81c5c55614beccc74de27373790c0d9757e94..eef9d37935e797c5d51fe1bf890bb010709669e5 100644 GIT binary patch delta 69 zcmbQGeMgILIWI340}$Aq=Ra-$*9#Z9 delta 131 zcmcbkHA|asIWI340}!wmb7bA-+Q_HDnUs;^0QKtOZ0OSi?UNoz+&;q`8hzL{G#}RoWzo}{Gwd_q|&ss OR3tvg{LOKk|F{8_PcRn% diff --git a/app/__pycache__/models.cpython-311.pyc b/app/__pycache__/models.cpython-311.pyc index fc97c345f0654ba9be2b269d549c1c6e3acee6d9..9f5a968be7103867d3d43b6da36a5d0ff7eb6fff 100644 GIT binary patch delta 74 zcmaE=yj+=gIWI340}$Aq$a{^2@z&%gES4GuE>_~h$a{^2@z>-hESB|o`iTVv`sMjW*_nCiV7j;}A73Tx3p8eP9IGb}0KE=8oB#j- diff --git a/app/__pycache__/schemas.cpython-311.pyc b/app/__pycache__/schemas.cpython-311.pyc index 7cafdde1dd317392a05c2a139f7ae4a2da0a9481..0e2ed94b8537233e9179719ca1b2f53bcd580c7d 100644 GIT binary patch delta 47 zcmbPdw9AlpIWI340}$AqPJGCgjJijQrxF9h(H6}SfDZj)> z&mcY=DCCh}RGb=~w rVsaCUvQtaIV)4oOIY6QOqWFTG#FDi9qTHCI(zG<7ots5imWcoW@yj}h diff --git a/app/api/__pycache__/__init__.cpython-311.pyc b/app/api/__pycache__/__init__.cpython-311.pyc index 948dd229f28b7f4ec5b7a015b4e81353f89129d5..2b2a5c5892849c37daf390e1b31a1e289f2389c0 100644 GIT binary patch delta 69 zcmaFJxR{Z5IWI340}$AqhrzIWI340}$xsaAdJf98>@R delta 163 zcmZ2h{G^y~IWI340}yC;b7Z|z+sG%!R$ru_SWuu}o?n!mnU@ZxiwhEyQ;YReQqvMk zb4v7!GZKqZ<5Ln#67>s;^0QKtOZ0OSi?UNoz+&;q`8hzL{G#}RoWzo}{Gwd_q|&ss rR3tvg{KSGx{p9?-w9It9g32OkpcBA^B*W%hwq@dsw>FE&O_Bxx%4j)@ diff --git a/app/api/__pycache__/data.cpython-311.pyc b/app/api/__pycache__/data.cpython-311.pyc index c75b420c00984d3b5f824d4200c78d570a3cb476..0ca2fc996f8710a3210ea45e6aadf9d86e2c30eb 100644 GIT binary patch delta 80 zcmZ4M^WK|pIWI340}$Aqb*dNHZoR^o20SN3)a%KriZsdE+&iHHcC-#>*#x7Pdi8%!siSgz6McKs#iOH!k gNu_CNsYUSxIf*4{`9--gi3J5foEfv(m9s-006!BP(*OVf delta 162 zcmeAVJR8WjoR^o20SLOoIJ2B2Hu61YXS_A}6Z^~hLjA;o0{!y*qU_APbTD09keHlW zte=vamROooqF~vm6}|lpPN{eomv7Gi%-ta0Se_8#TVoxmZaqu uP%7G&y|Bo=2E>lIYq;!iG0O)N=`&r2vfEDr!FsXd?o diff --git a/app/services/__pycache__/__init__.cpython-311.pyc b/app/services/__pycache__/__init__.cpython-311.pyc index 0fe3f4ce0cbfcd1c8161b41b69d09810118be13c..ebac38bb89482c978e4f4472c396d47478251009 100644 GIT binary patch delta 74 zcmaFHxPp;)IWI340}$AqOwS>(@^9Y!w|GnSt=!wW(_!5w z9s7EAXMO>Sz>_s~<85aV3{;?@h*LHwEh_m24MCK93I+peBHNu0oL9x_C8I^w0j^Vw P^!K-ZA$@dPb-rJI!`?D? diff --git a/app/services/__pycache__/cache.cpython-311.pyc b/app/services/__pycache__/cache.cpython-311.pyc index 8c19002b5e670acbe07810661cdc199dc5d576e6..7732f0cde53ed5498c4236639ed30889cefccaae 100644 GIT binary patch delta 78 zcmbOeb1#~2IWI340}$Aq#Ot=3kvkh^NX@G^U}d|aY15o zYO#JwYFc7xPKkbTMq*KFd`e +
+ +
@@ -1805,12 +1811,14 @@ if (!res.ok) { showToast(data.detail || '未找到缓存数据', 'error'); + document.getElementById('btnExportData').disabled = true; return; } addLog(`查询成功: ${symbol}, 缓存 ${data.timeframes ? data.timeframes.length : 0} 个周期`, 'success'); currentQueryData = data; + document.getElementById('btnExportData').disabled = false; if (!data.timeframes || data.timeframes.length === 0) { document.getElementById('queryResult').innerHTML = '

暂无K线数据

'; @@ -1822,7 +1830,49 @@ } catch (e) { showToast(`查询失败: ${e.message}`, 'error'); + document.getElementById('btnExportData').disabled = true; + } + } + + function exportData() { + if (!currentQueryData || !currentQueryData.timeframes || currentQueryData.timeframes.length === 0) { + showToast('暂无可导出的数据', 'error'); + return; } + + const symbol = document.getElementById('querySymbol').value.trim() || 'unknown'; + const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19); + const filename = `${symbol}_多周期数据_${timestamp}.json`; + + const exportObj = { + symbol: currentQueryData.symbol || symbol, + type: currentQueryData.type || 'futures', + current_price: currentQueryData.current_price, + timestamp: currentQueryData.timestamp || new Date().toISOString(), + timeframes: {} + }; + + currentQueryData.timeframes.forEach(tf => { + exportObj.timeframes[tf.period] = tf.candles || []; + }); + + const jsonStr = JSON.stringify(exportObj, null, 2); + const blob = new Blob([jsonStr], { type: 'application/json' }); + const url = URL.createObjectURL(blob); + + const a = document.createElement('a'); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + + const periodCount = currentQueryData.timeframes.length; + const totalCandles = currentQueryData.timeframes.reduce((sum, tf) => sum + (tf.candles ? tf.candles.length : 0), 0); + + addLog(`数据导出成功: ${filename}, ${periodCount} 个周期, ${totalCandles} 条K线`, 'success'); + showToast(`已导出 ${periodCount} 个周期数据`, 'success'); } function renderKlineChart(timeframe, symbol) {