diff --git a/app/api/__pycache__/futures_analysis.cpython-311.pyc b/app/api/__pycache__/futures_analysis.cpython-311.pyc index b7939f6..7dd0b8a 100644 Binary files a/app/api/__pycache__/futures_analysis.cpython-311.pyc and b/app/api/__pycache__/futures_analysis.cpython-311.pyc differ diff --git a/app/api/futures_analysis.py b/app/api/futures_analysis.py index 72db2e8..b1825de 100644 --- a/app/api/futures_analysis.py +++ b/app/api/futures_analysis.py @@ -216,6 +216,10 @@ def get_kline_data(symbol: str, period: str = "15", db: Session = Depends(get_db def _get_futures_name(symbol: str) -> str: """根据合约代码获取品种名称""" + # 从合约代码中提取品种代码(去除数字部分) + import re + symbol_base = re.sub(r'\d+', '', symbol).upper() + name_map = { "AU": "黄金", "AG": "白银", "CU": "铜", "AL": "铝", "ZN": "锌", "NI": "镍", "SN": "锡", "PB": "铅", @@ -232,7 +236,7 @@ def _get_futures_name(symbol: str) -> str: "IF": "沪深300", "IC": "中证500", "IH": "上证50", "IM": "中证1000", "T": "10年期国债", "TF": "5年期国债", "TS": "2年期国债", "TL": "30年期国债", } - return name_map.get(symbol, symbol) + return name_map.get(symbol_base, symbol) def _get_suggestion(close: float, open: float, change_pct: float) -> str: diff --git a/app/static/futures_analysis.html b/app/static/futures_analysis.html index 912082f..acabc4a 100644 --- a/app/static/futures_analysis.html +++ b/app/static/futures_analysis.html @@ -132,7 +132,11 @@ .card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); } .card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 16px; } - .code-box { width: 36px; height: 36px; background: #F5F5F7; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600; color: var(--text-tertiary); margin-bottom: 8px; } + .card-left { display: flex; gap: 12px; align-items: flex-start; } + .code-box { width: 36px; height: 36px; background: #F5F5F7; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600; color: var(--text-tertiary); } + .info-group { display: flex; flex-direction: column; } + .name-row { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 15px; } + .contract-code { font-size: 12px; color: var(--text-tertiary); margin-top: 2px; } .price-area { text-align: right; } .price { font-size: 28px; font-weight: 700; letter-spacing: -0.02em; line-height: 1; } .price.up { color: var(--color-up); } @@ -170,6 +174,10 @@ .support-resist .green { color: var(--color-down); } .link { color: var(--color-brand); font-weight: 500; text-decoration: none; } .link:hover { text-decoration: underline; } + + .fav-icon { font-size: 15px; color: #D1D1D6; cursor: pointer; transition: all 0.2s; display: inline-flex; align-items: center; user-select: none; } + .fav-icon:hover { color: #FF9F0A; } + .fav-icon.active { color: #FF9F0A; transform: scale(1.1); } /* 详情视图样式 */ .view { display: none; } diff --git a/app/static/futures_analysis.js b/app/static/futures_analysis.js index 340e35c..31c6fc9 100644 --- a/app/static/futures_analysis.js +++ b/app/static/futures_analysis.js @@ -279,6 +279,14 @@ async function toggleWatch(symbol, name, event) { } } +function toggleFav(symbol, name, event) { + event.stopPropagation(); + + // 调用原有的toggleWatch函数处理API请求和数据更新 + // toggleWatch 会重新渲染网格,星标状态会根据 watchedSymbols 自动更新 + toggleWatch(symbol, name, event); +} + function getCurrentFilteredData() { const activePill = document.querySelector('.pill.active'); const category = activePill ? activePill.dataset.category : 'all'; @@ -512,10 +520,12 @@ function renderFuturesGrid(data) { return `