更新Company页面的UI为FUI风格

This commit is contained in:
2025-12-22 15:31:10 +08:00
parent 6d878df27c
commit 20bcf3770a
2 changed files with 98 additions and 25 deletions

66
app.py
View File

@@ -11279,35 +11279,60 @@ def get_events_by_mainline():
else: else:
ungrouped_events.append(event_data) ungrouped_events.append(event_data)
# ==================== 5. 获取 lv2 概念涨跌幅 ==================== # ==================== 5. 获取概念涨跌幅(根据 group_by 参数) ====================
lv2_price_map = {} 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: try:
# 获取所有 lv2 名称 # 获取所有对应层级的名称
lv2_names = [group['lv2_name'] for group in mainline_groups.values() if group.get('lv2_name')] group_names = [group.get('group_name') or group.get(name_field) for group in mainline_groups.values()]
if lv2_names: group_names = [n for n in group_names if n] # 过滤掉空值
# 数据库中的 concept_name 带有 "[二级] " 前缀,需要添加前缀来匹配
lv2_names_with_prefix = [f'[二级] {name}' for name in lv2_names] if group_names:
# 数据库中的 concept_name 带有前缀,需要添加前缀来匹配
names_with_prefix = [f'{name_prefix}{name}' for name in group_names]
# 查询 concept_daily_stats 表获取最新涨跌幅 # 查询 concept_daily_stats 表获取最新涨跌幅
price_sql = text(''' price_sql = text('''
SELECT concept_name, avg_change_pct, trade_date SELECT concept_name, avg_change_pct, trade_date
FROM concept_daily_stats FROM concept_daily_stats
WHERE concept_type = 'lv2' WHERE concept_type = :concept_type
AND concept_name IN :names AND concept_name IN :names
AND trade_date = ( 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: for row in price_result:
# 去掉 "[二级] " 前缀,用原始名称作为 key # 去掉前缀,用原始名称作为 key
original_name = row.concept_name.replace('[二级] ', '') if row.concept_name else '' original_name = row.concept_name.replace(name_prefix, '') if row.concept_name else ''
lv2_price_map[original_name] = { price_map[original_name] = {
'avg_change_pct': float(row.avg_change_pct) if row.avg_change_pct else None, '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 '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: except Exception as price_err:
app.logger.warning(f'[mainline] 获取 lv2 涨跌幅失败: {price_err}') app.logger.warning(f'[mainline] 获取 {current_level} 涨跌幅失败: {price_err}')
# ==================== 6. 整理返回数据 ==================== # ==================== 6. 整理返回数据 ====================
mainlines = [] mainlines = []
@@ -11319,11 +11344,12 @@ def get_events_by_mainline():
reverse=True reverse=True
) )
group['event_count'] = len(group['events']) 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_name = group.get('group_name') or group.get(name_field, '')
group['avg_change_pct'] = lv2_price_map[lv2_name]['avg_change_pct'] if group_name in price_map:
group['price_date'] = lv2_price_map[lv2_name]['trade_date'] group['avg_change_pct'] = price_map[group_name]['avg_change_pct']
group['price_date'] = price_map[group_name]['trade_date']
else: else:
group['avg_change_pct'] = None group['avg_change_pct'] = None
group['price_date'] = None group['price_date'] = None

View File

@@ -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) const mainlines = Object.values(mainlineGroups)
.map(group => ({ .map(group => {
...group, // 根据分组层级获取对应的涨跌幅
events: group.events.slice(0, limitPerMainline), let avgChangePct = null;
event_count: Math.min(group.events.length, limitPerMainline) 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) .filter(group => group.event_count > 0)
.sort((a, b) => b.event_count - a.event_count); .sort((a, b) => b.event_count - a.event_count);