From e32c13689d30cbeff00dabe36cc39bbd73cf0908 Mon Sep 17 00:00:00 2001 From: Lxy Date: Tue, 7 Jul 2026 23:33:45 +0800 Subject: [PATCH] =?UTF-8?q?tweak:=20=E5=93=81=E7=A7=8D=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=88=86=E7=B1=BB=E6=94=B9=E4=B8=BA=20tab=20=E5=88=87=E6=8D=A2?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/static/index.html | 141 ++++++++++++++++++++++++++++++------------ 1 file changed, 100 insertions(+), 41 deletions(-) diff --git a/app/static/index.html b/app/static/index.html index 195337a..a77c5b2 100644 --- a/app/static/index.html +++ b/app/static/index.html @@ -365,13 +365,43 @@ font-size: 12px; } - .symbol-table .symbol-category-row td { - background: var(--primary-light); - color: white; - font-weight: 600; - font-size: 13px; + /* 分类 Tab 样式 */ + .category-tabs-container { + margin-top: 16px; + } + + .category-tabs { + display: flex; + gap: 8px; + margin-bottom: 16px; + flex-wrap: wrap; + } + + .category-tab { padding: 8px 16px; - border-bottom: none; + border: 1px solid var(--gray-300); + background: white; + border-radius: 6px; + font-size: 13px; + font-weight: 500; + color: var(--gray-700); + cursor: pointer; + transition: all 0.2s; + } + + .category-tab:hover { + border-color: var(--primary-light); + color: var(--primary); + } + + .category-tab.active { + background: var(--primary); + border-color: var(--primary); + color: white; + } + + .category-content { + margin-top: 0; } .add-symbol-form { @@ -1523,7 +1553,7 @@ const stockCount = Object.keys(stock).length; document.getElementById('configCount').textContent = `期货 ${futuresCount} 个, 股票 ${stockCount} 个`; - const renderTable = (items, type) => { + const renderTable = (items, type, containerId) => { let filteredItems = items; if (currentSearchTerm) { @@ -1556,52 +1586,81 @@ grouped[category].push({ name, code }); } - // 按分类顺序渲染 - let tbodyHtml = ''; + // 获取有数据的分类列表 + const activeCategories = []; for (const category of CATEGORY_ORDER) { - if (!grouped[category] || grouped[category].length === 0) continue; - tbodyHtml += `${category}`; - for (const { name, code } of grouped[category]) { - tbodyHtml += ` - ${highlightText(name)} - - - - - - `; + if (grouped[category] && grouped[category].length > 0) { + activeCategories.push(category); } } // 处理未在映射表中的分类 - for (const [category, symbols] of Object.entries(grouped)) { - if (CATEGORY_ORDER.includes(category)) continue; - tbodyHtml += `${category}`; - for (const { name, code } of symbols) { - tbodyHtml += ` + for (const category of Object.keys(grouped)) { + if (!CATEGORY_ORDER.includes(category) && grouped[category].length > 0) { + activeCategories.push(category); + } + } + + if (activeCategories.length === 0) { + return '

暂无品种

'; + } + + // 生成 tab 导航 + const tabsHtml = activeCategories.map((category, index) => + `` + ).join(''); + + // 生成表格内容(每个分类一个表格,默认只显示第一个) + const tablesHtml = activeCategories.map((category, index) => { + const rows = grouped[category].map(({ name, code }) => + ` ${highlightText(name)} - `; - } - } - - return ` - - - - - - - - ${tbodyHtml} -
品种名称合约代码操作
`; + ` + ).join(''); + + return `
+ + + + + + + + + ${rows} +
品种名称合约代码操作
+
`; + }).join(''); + + return `
+
${tabsHtml}
+
${tablesHtml}
+
`; }; - document.getElementById('tab-futures').innerHTML = renderTable(futures, 'futures'); - document.getElementById('tab-stock').innerHTML = renderTable(stock, 'stock'); + document.getElementById('tab-futures').innerHTML = renderTable(futures, 'futures', 'futures'); + document.getElementById('tab-stock').innerHTML = renderTable(stock, 'stock', 'stock'); + } + + // 切换分类 tab + function switchCategoryTab(containerId, category, btn) { + const container = btn.closest('.category-tabs-container'); + + // 更新 tab 按钮状态 + container.querySelectorAll('.category-tab').forEach(tab => tab.classList.remove('active')); + btn.classList.add('active'); + + // 显示对应的表格 + container.querySelectorAll('.category-table-wrapper').forEach(wrapper => { + wrapper.style.display = wrapper.dataset.category === category ? 'block' : 'none'; + }); } function filterSymbols(searchTerm) {