From 20bcf3770aadffeff01b53a19cbf9175f127c010 Mon Sep 17 00:00:00 2001 From: zzlgreat Date: Mon, 22 Dec 2025 15:31:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0Company=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E7=9A=84UI=E4=B8=BAFUI=E9=A3=8E=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.py | 66 ++++++++++++++++++++++++++----------- src/mocks/handlers/event.js | 57 +++++++++++++++++++++++++++++--- 2 files changed, 98 insertions(+), 25 deletions(-) diff --git a/app.py b/app.py index 0561471e..7a1ba37c 100755 --- a/app.py +++ b/app.py @@ -11279,35 +11279,60 @@ def get_events_by_mainline(): else: ungrouped_events.append(event_data) - # ==================== 5. 获取 lv2 概念涨跌幅 ==================== - lv2_price_map = {} + # ==================== 5. 获取概念涨跌幅(根据 group_by 参数) ==================== + price_map = {} + + # 确定当前分组层级和对应的数据库类型 + if group_by == 'lv1' or group_by.startswith('L1_'): + current_level = 'lv1' + db_concept_type = 'lv1' + name_prefix = '[一级] ' + name_field = 'lv1_name' + elif group_by == 'lv3' or group_by.startswith('L2_'): + current_level = 'lv3' + db_concept_type = 'lv3' + name_prefix = '[三级] ' + name_field = 'lv3_name' + else: # lv2 或 L3_ 开头(查看 lv3 下的具体分类,显示 lv2 涨跌幅) + current_level = 'lv2' + db_concept_type = 'lv2' + name_prefix = '[二级] ' + name_field = 'lv2_name' + try: - # 获取所有 lv2 名称 - lv2_names = [group['lv2_name'] for group in mainline_groups.values() if group.get('lv2_name')] - if lv2_names: - # 数据库中的 concept_name 带有 "[二级] " 前缀,需要添加前缀来匹配 - lv2_names_with_prefix = [f'[二级] {name}' for name in lv2_names] + # 获取所有对应层级的名称 + group_names = [group.get('group_name') or group.get(name_field) for group in mainline_groups.values()] + group_names = [n for n in group_names if n] # 过滤掉空值 + + if group_names: + # 数据库中的 concept_name 带有前缀,需要添加前缀来匹配 + names_with_prefix = [f'{name_prefix}{name}' for name in group_names] + # 查询 concept_daily_stats 表获取最新涨跌幅 price_sql = text(''' SELECT concept_name, avg_change_pct, trade_date FROM concept_daily_stats - WHERE concept_type = 'lv2' + WHERE concept_type = :concept_type AND concept_name IN :names AND trade_date = ( - SELECT MAX(trade_date) FROM concept_daily_stats WHERE concept_type = 'lv2' + SELECT MAX(trade_date) FROM concept_daily_stats WHERE concept_type = :concept_type ) ''') - price_result = db.session.execute(price_sql, {'names': tuple(lv2_names_with_prefix)}).fetchall() + price_result = db.session.execute(price_sql, { + 'concept_type': db_concept_type, + 'names': tuple(names_with_prefix) + }).fetchall() + for row in price_result: - # 去掉 "[二级] " 前缀,用原始名称作为 key - original_name = row.concept_name.replace('[二级] ', '') if row.concept_name else '' - lv2_price_map[original_name] = { + # 去掉前缀,用原始名称作为 key + original_name = row.concept_name.replace(name_prefix, '') if row.concept_name else '' + price_map[original_name] = { 'avg_change_pct': float(row.avg_change_pct) if row.avg_change_pct else None, 'trade_date': str(row.trade_date) if row.trade_date else None } - app.logger.info(f'[mainline] 获取 lv2 涨跌幅: {len(lv2_price_map)} 条, lv2_names 数量: {len(lv2_names)}') + app.logger.info(f'[mainline] 获取 {current_level} 涨跌幅: {len(price_map)} 条, 查询名称数量: {len(group_names)}') except Exception as price_err: - app.logger.warning(f'[mainline] 获取 lv2 涨跌幅失败: {price_err}') + app.logger.warning(f'[mainline] 获取 {current_level} 涨跌幅失败: {price_err}') # ==================== 6. 整理返回数据 ==================== mainlines = [] @@ -11319,11 +11344,12 @@ def get_events_by_mainline(): reverse=True ) group['event_count'] = len(group['events']) - # 添加涨跌幅数据(目前只支持 lv2) - lv2_name = group.get('lv2_name', '') or group.get('group_name', '') - if lv2_name in lv2_price_map: - group['avg_change_pct'] = lv2_price_map[lv2_name]['avg_change_pct'] - group['price_date'] = lv2_price_map[lv2_name]['trade_date'] + + # 添加涨跌幅数据(根据当前分组层级) + group_name = group.get('group_name') or group.get(name_field, '') + if group_name in price_map: + group['avg_change_pct'] = price_map[group_name]['avg_change_pct'] + group['price_date'] = price_map[group_name]['trade_date'] else: group['avg_change_pct'] = None group['price_date'] = None diff --git a/src/mocks/handlers/event.js b/src/mocks/handlers/event.js index 6d9aceca..c609c206 100644 --- a/src/mocks/handlers/event.js +++ b/src/mocks/handlers/event.js @@ -1726,12 +1726,59 @@ export const eventHandlers = [ }); }); + // 生成各层级的模拟涨跌幅数据 + const generatePriceData = () => { + // 生成 -5% 到 +8% 之间的随机涨跌幅 + return parseFloat((Math.random() * 13 - 5).toFixed(2)); + }; + + // 为各层级生成涨跌幅 Map + const priceDataMap = { + lv1: {}, + lv2: {}, + lv3: {} + }; + + // 为每个层级生成涨跌幅 + mainlineDefinitions.forEach(def => { + if (!priceDataMap.lv1[def.lv1_name]) { + priceDataMap.lv1[def.lv1_name] = generatePriceData(); + } + if (!priceDataMap.lv2[def.lv2_name]) { + priceDataMap.lv2[def.lv2_name] = generatePriceData(); + } + if (!priceDataMap.lv3[def.lv3_name]) { + priceDataMap.lv3[def.lv3_name] = generatePriceData(); + } + }); + const mainlines = Object.values(mainlineGroups) - .map(group => ({ - ...group, - events: group.events.slice(0, limitPerMainline), - event_count: Math.min(group.events.length, limitPerMainline) - })) + .map(group => { + // 根据分组层级获取对应的涨跌幅 + let avgChangePct = null; + if (groupBy === 'lv1' || groupBy.startsWith('L1_')) { + // lv1 分组,使用 lv1 涨跌幅(如果是 L1_ 开头,则显示的是 lv2 分组,使用 lv2 涨跌幅) + if (groupBy.startsWith('L1_')) { + avgChangePct = priceDataMap.lv2[group.group_name] ?? null; + } else { + avgChangePct = priceDataMap.lv1[group.group_name] ?? null; + } + } else if (groupBy === 'lv3' || groupBy.startsWith('L2_')) { + // lv3 分组,使用 lv3 涨跌幅 + avgChangePct = priceDataMap.lv3[group.group_name] ?? null; + } else { + // lv2 分组(默认),使用 lv2 涨跌幅 + avgChangePct = priceDataMap.lv2[group.group_name] ?? null; + } + + return { + ...group, + events: group.events.slice(0, limitPerMainline), + event_count: Math.min(group.events.length, limitPerMainline), + avg_change_pct: avgChangePct, + price_date: new Date().toISOString().split('T')[0] + }; + }) .filter(group => group.event_count > 0) .sort((a, b) => b.event_count - a.event_count);