Merge branch 'feature_bugfix/251201_py_h5_ui' of https://git.valuefrontier.cn/vf/vf_react into feature_bugfix/251201_py_h5_ui

This commit is contained in:
2025-12-16 14:48:46 +08:00
8 changed files with 1220 additions and 338 deletions

View File

@@ -31,6 +31,8 @@ export interface TradeDatePickerProps {
showIcon?: boolean;
/** 是否使用深色模式(强制覆盖 Chakra 颜色模式) */
isDarkMode?: boolean;
/** 是否显示最新交易日期提示,默认 true */
showLatestTradeDateTip?: boolean;
}
/**
@@ -50,6 +52,7 @@ const TradeDatePicker: React.FC<TradeDatePickerProps> = ({
inputWidth = { base: '100%', lg: '200px' },
showIcon = true,
isDarkMode = false,
showLatestTradeDateTip = true,
}) => {
// 颜色主题 - 支持 isDarkMode 强制覆盖
const defaultLabelColor = useColorModeValue('purple.700', 'purple.300');
@@ -142,21 +145,21 @@ const TradeDatePicker: React.FC<TradeDatePickerProps> = ({
} : undefined}
/>
{/* 最新交易日期提示 */}
{latestTradeDate && (
{/* 最新交易日期提示 - 靠右显示,样式更低调避免误认为按钮 */}
{showLatestTradeDateTip && latestTradeDate && (
<Tooltip label="数据库中最新的交易日期">
<HStack
spacing={2}
bg={tipBg}
px={3}
py={1.5}
borderRadius="full"
border="1px solid"
borderColor={tipBorderColor}
spacing={1.5}
ml="auto"
px={2}
py={1}
opacity={0.7}
_hover={{ opacity: 1 }}
transition="opacity 0.2s"
>
<Icon as={InfoIcon} color={tipIconColor} boxSize={3} />
<Text fontSize="sm" color={tipTextColor} fontWeight="medium">
: {latestTradeDate.toLocaleDateString('zh-CN')}
<Text fontSize="xs" color={tipTextColor}>
{latestTradeDate.toLocaleDateString('zh-CN')}
</Text>
</HStack>
</Tooltip>

View File

@@ -336,17 +336,34 @@ export const conceptHandlers = [
});
}),
// 获取最新交易日期
// 获取最新交易日期 - 硬编码 URL开发环境
http.get('http://111.198.58.126:16801/price/latest', async () => {
await delay(200);
const today = new Date();
const dateStr = today.toISOString().split('T')[0].replace(/-/g, '');
// 使用 YYYY-MM-DD 格式,确保 new Date() 可以正确解析
const dateStr = today.toISOString().split('T')[0];
console.log('[Mock Concept] 获取最新交易日期:', dateStr);
return HttpResponse.json({
latest_date: dateStr,
latest_trade_date: dateStr,
timestamp: today.toISOString()
});
}),
// 获取最新交易日期 - 相对路径MSW 环境)
http.get('/concept-api/price/latest', async () => {
await delay(200);
const today = new Date();
// 使用 YYYY-MM-DD 格式,确保 new Date() 可以正确解析
const dateStr = today.toISOString().split('T')[0];
console.log('[Mock Concept] 获取最新交易日期 (概念API):', dateStr);
return HttpResponse.json({
latest_trade_date: dateStr,
timestamp: today.toISOString()
});
}),
@@ -393,6 +410,48 @@ export const conceptHandlers = [
}
}),
// 搜索概念MSW 代理路径)
http.post('/concept-api/search', async ({ request }) => {
await delay(300);
try {
const body = await request.json();
const { query = '', size = 20, page = 1, sort_by = 'change_pct' } = body;
console.log('[Mock Concept] 搜索概念 (concept-api):', { query, size, page, sort_by });
let results = generatePopularConcepts(size);
if (query) {
results = results.filter(item =>
item.concept.toLowerCase().includes(query.toLowerCase())
);
}
if (sort_by === 'change_pct') {
results.sort((a, b) => b.price_info.avg_change_pct - a.price_info.avg_change_pct);
} else if (sort_by === 'stock_count') {
results.sort((a, b) => b.stock_count - a.stock_count);
} else if (sort_by === 'hot_score') {
results.sort((a, b) => b.hot_score - a.hot_score);
}
return HttpResponse.json({
results,
total: results.length,
page,
size,
message: '搜索成功'
});
} catch (error) {
console.error('[Mock Concept] 搜索失败 (concept-api):', error);
return HttpResponse.json(
{ results: [], total: 0, error: '搜索失败' },
{ status: 500 }
);
}
}),
// 获取统计数据(直接访问外部 API
http.get('http://111.198.58.126:16801/statistics', async ({ request }) => {
await delay(300);
@@ -592,13 +651,13 @@ export const conceptHandlers = [
// ============ 层级结构 API ============
// 获取完整层级结构
http.get('/concept-api/hierarchy', async () => {
// 获取完整层级结构(硬编码 URL - 开发环境)
http.get('http://111.198.58.126:16801/hierarchy', async () => {
await delay(300);
console.log('[Mock Concept] 获取层级结构');
console.log('[Mock Concept] 获取层级结构 (硬编码URL)');
// 模拟层级结构数据
// 模拟完整的层级结构数据
const hierarchy = [
{
id: 'lv1_1',
@@ -610,24 +669,24 @@ export const conceptHandlers = [
name: 'AI基础设施',
concept_count: 52,
children: [
{ id: 'lv3_1_1_1', name: 'AI算力硬件', concept_count: 16, concepts: ['AI芯片', 'GPU概念股', '服务器', 'AI一体机'] },
{ id: 'lv3_1_1_2', name: 'AI关键组件', concept_count: 24, concepts: ['HBM', 'PCB', '光通信', '存储芯片'] },
{ id: 'lv3_1_1_3', name: 'AI配套设施', concept_count: 12, concepts: ['数据中心', '液冷', '电力设备'] }
{ id: 'lv3_1_1_1', name: 'AI算力硬件', concept_count: 16, concepts: ['AI芯片', 'GPU概念股', '服务器', 'AI一体机', '算力租赁', 'NPU', '智能计算中心', '超算中心'] },
{ id: 'lv3_1_1_2', name: 'AI关键组件', concept_count: 24, concepts: ['HBM', 'PCB', '光通信', '存储芯片', 'CPO', '光模块', '铜连接', '高速背板'] },
{ id: 'lv3_1_1_3', name: 'AI配套设施', concept_count: 12, concepts: ['数据中心', '液冷', '电力设备', 'UPS', 'IDC服务', '边缘计算', 'AI电源'] }
]
},
{
id: 'lv2_1_2',
name: 'AI模型与软件',
concept_count: 13,
concepts: ['DeepSeek', 'KIMI', 'SORA概念', '国产大模型']
concept_count: 18,
concepts: ['DeepSeek', 'KIMI', 'SORA概念', '国产大模型', 'ChatGPT', 'Claude', '文心一言', '通义千问', 'Gemini概念', 'AI推理']
},
{
id: 'lv2_1_3',
name: 'AI应用',
concept_count: 17,
concept_count: 28,
children: [
{ id: 'lv3_1_3_1', name: '智能体与陪伴', concept_count: 11, concepts: ['AI伴侣', 'AI智能体', 'AI陪伴'] },
{ id: 'lv3_1_3_2', name: '行业应用', concept_count: 6, concepts: ['AI编程', '低代码'] }
{ id: 'lv3_1_3_1', name: '智能体与陪伴', concept_count: 11, concepts: ['AI伴侣', 'AI智能体', 'AI陪伴', 'AI助手', '数字人', 'AI语音', 'AI社交'] },
{ id: 'lv3_1_3_2', name: '行业应用', concept_count: 17, concepts: ['AI编程', '低代码', 'AI教育', 'AI医疗', 'AI金融', 'AI制造', 'AI安防', 'AI营销', 'AI设计'] }
]
}
]
@@ -635,71 +694,320 @@ export const conceptHandlers = [
{
id: 'lv1_2',
name: '半导体',
concept_count: 45,
concept_count: 65,
children: [
{ id: 'lv2_2_1', name: '半导体设备', concept_count: 10, concepts: ['光刻机', 'EDA', '半导体设备'] },
{ id: 'lv2_2_2', name: '半导体材料', concept_count: 8, concepts: ['光刻胶', '半导体材料', '石英砂'] },
{ id: 'lv2_2_3', name: '芯片设计与制造', concept_count: 10, concepts: ['第三代半导体', '碳化硅', '功率半导体'] },
{ id: 'lv2_2_4', name: '先进封装', concept_count: 5, concepts: ['玻璃基板', '半导体封测'] }
{ id: 'lv2_2_1', name: '半导体设备', concept_count: 18, concepts: ['光刻机', '刻蚀设备', '薄膜沉积', '离子注入', 'CMP设备', '清洗设备'] },
{ id: 'lv2_2_2', name: '半导体材料', concept_count: 15, concepts: ['光刻胶', '半导体材料', '石英砂', '硅片', '电子特气', '靶材', 'CMP抛光液'] },
{ id: 'lv2_2_3', name: '芯片设计与制造', concept_count: 22, concepts: ['CPU', 'GPU', 'FPGA', 'ASIC', 'MCU', 'DSP', 'NPU芯片', '功率半导体', '碳化硅'] },
{ id: 'lv2_2_4', name: '先进封装', concept_count: 10, concepts: ['玻璃基板', '半导体封测', 'Chiplet', 'CoWoS', 'SiP', '3D封装'] }
]
},
{
id: 'lv1_3',
name: '机器人',
concept_count: 42,
concept_count: 52,
children: [
{ id: 'lv2_3_1', name: '人形机器人整机', concept_count: 20, concepts: ['特斯拉机器人', '人形机器人', '智元机器人'] },
{ id: 'lv2_3_2', name: '机器人核心零部件', concept_count: 12, concepts: ['滚柱丝杆', '电子皮肤', '轴向磁通电机'] },
{ id: 'lv2_3_3', name: '其他类型机器人', concept_count: 10, concepts: ['工业机器人', '机器狗', '外骨骼机器人'] }
{ id: 'lv2_3_1', name: '人形机器人整机', concept_count: 20, concepts: ['特斯拉机器人', '人形机器人', '智元机器人', '优必选', '小米机器人', '华为机器人'] },
{ id: 'lv2_3_2', name: '机器人核心零部件', concept_count: 20, concepts: ['滚柱丝杆', '电子皮肤', '轴向磁通电机', '谐波减速器', '行星减速器', '伺服电机', '六维力传感器', '灵巧手'] },
{ id: 'lv2_3_3', name: '其他类型机器人', concept_count: 12, concepts: ['工业机器人', '机器狗', '外骨骼机器人', '协作机器人', '手术机器人', '服务机器人'] }
]
},
{
id: 'lv1_4',
name: '消费电子',
concept_count: 38,
concept_count: 48,
children: [
{ id: 'lv2_4_1', name: '智能终端', concept_count: 8, concepts: ['AI PC', 'AI手机'] },
{ id: 'lv2_4_2', name: 'XR与空间计算', concept_count: 14, concepts: ['AR眼镜', 'MR', '智能眼镜'] },
{ id: 'lv2_4_3', name: '华为产业链', concept_count: 16, concepts: ['华为Mate70', '鸿蒙', '华为昇腾'] }
{ id: 'lv2_4_1', name: '智能终端', concept_count: 12, concepts: ['AI PC', 'AI手机', '折叠屏', '卫星通信手机', '智能手表', '智能耳机'] },
{ id: 'lv2_4_2', name: 'XR与空间计算', concept_count: 18, concepts: ['AR眼镜', 'MR', '智能眼镜', 'VR头显', 'Apple Vision Pro概念', 'Meta Quest概念'] },
{ id: 'lv2_4_3', name: '华为产业链', concept_count: 18, concepts: ['华为Mate70', '鸿蒙', '华为昇腾', '华为汽车', '华为海思', '华为云', '麒麟芯片'] }
]
},
{
id: 'lv1_5',
name: '智能驾驶与汽车',
concept_count: 35,
concept_count: 45,
children: [
{ id: 'lv2_5_1', name: '自动驾驶解决方案', concept_count: 12, concepts: ['Robotaxi', '无人驾驶', '特斯拉FSD'] },
{ id: 'lv2_5_2', name: '智能汽车产业链', concept_count: 15, concepts: ['比亚迪产业链', '小米汽车产业链'] },
{ id: 'lv2_5_3', name: '车路协同', concept_count: 8, concepts: ['车路云一体化', '车路协同'] }
{ id: 'lv2_5_1', name: '自动驾驶解决方案', concept_count: 18, concepts: ['Robotaxi', '无人驾驶', '特斯拉FSD', 'L4自动驾驶', '萝卜快跑', '百度Apollo'] },
{ id: 'lv2_5_2', name: '智能汽车产业链', concept_count: 18, concepts: ['比亚迪产业链', '小米汽车产业链', '特斯拉产业链', '新能源汽车', '智能座舱', '汽车电子'] },
{ id: 'lv2_5_3', name: '车路协同', concept_count: 9, concepts: ['车路云一体化', '车路协同', 'V2X', '智能交通', '高精地图', '车联网'] }
]
},
{
id: 'lv1_6',
name: '新能源与电力',
concept_count: 52,
concept_count: 62,
children: [
{ id: 'lv2_6_1', name: '新型电池技术', concept_count: 18, concepts: ['固态电池', '钠离子电池', '硅基负极'] },
{ id: 'lv2_6_2', name: '电力设备与电网', concept_count: 20, concepts: ['电力', '变压器出海', '燃料电池'] },
{ id: 'lv2_6_3', name: '清洁能源', concept_count: 14, concepts: ['光伏', '核电', '可控核聚变'] }
{ id: 'lv2_6_1', name: '新型电池技术', concept_count: 22, concepts: ['固态电池', '钠离子电池', '锂电池', '磷酸铁锂', '三元锂电池', '硅基负极', '电解液'] },
{ id: 'lv2_6_2', name: '电力设备与电网', concept_count: 24, concepts: ['电力', '变压器出海', '特高压', '智能电网', '储能', '充电桩', '虚拟电厂'] },
{ id: 'lv2_6_3', name: '清洁能源', concept_count: 16, concepts: ['光伏', '核电', '可控核聚变', '风电', '海上风电', '氢能源', '绿电', '碳中和'] }
]
},
{
id: 'lv1_7',
name: '空天经济',
concept_count: 28,
concept_count: 38,
children: [
{ id: 'lv2_7_1', name: '低空经济', concept_count: 14, concepts: ['低空经济', 'eVTOL', '飞行汽车'] },
{ id: 'lv2_7_2', name: '商业航天', concept_count: 14, concepts: ['卫星互联网', '商业航天', '北斗导航'] }
{ id: 'lv2_7_1', name: '低空经济', concept_count: 20, concepts: ['低空经济', 'eVTOL', '飞行汽车', '无人机', '电动垂直起降', '载人飞行器', '物流无人机'] },
{ id: 'lv2_7_2', name: '商业航天', concept_count: 18, concepts: ['卫星互联网', '商业航天', '北斗导航', '星链概念', '火箭发射', '卫星制造', '遥感卫星'] }
]
},
{
id: 'lv1_8',
name: '国防军工',
concept_count: 35,
children: [
{ id: 'lv2_8_1', name: '无人作战与信息化', concept_count: 14, concepts: ['AI军工', '无人机蜂群', '军工信息化', '无人作战', '军用无人机', '电子战'] },
{ id: 'lv2_8_2', name: '海军装备', concept_count: 12, concepts: ['国产航母', '电磁弹射', '舰艇', '潜艇', '海军武器', '舰载机'] },
{ id: 'lv2_8_3', name: '军贸出海', concept_count: 9, concepts: ['军贸', '巴黎航展', '武器出口', '国际军贸', '军工出海'] }
]
}
];
return HttpResponse.json({
hierarchy,
total_lv1: hierarchy.length,
total_concepts: hierarchy.reduce((acc, h) => acc + h.concept_count, 0)
});
}),
// 获取完整层级结构(更丰富的 mock 数据)
http.get('/concept-api/hierarchy', async () => {
await delay(300);
console.log('[Mock Concept] 获取层级结构');
// 模拟完整的层级结构数据
const hierarchy = [
{
id: 'lv1_1',
name: '人工智能',
concept_count: 98,
children: [
{
id: 'lv2_1_1',
name: 'AI基础设施',
concept_count: 52,
children: [
{ id: 'lv3_1_1_1', name: 'AI算力硬件', concept_count: 16, concepts: ['AI芯片', 'GPU概念股', '服务器', 'AI一体机', '算力租赁', 'NPU', '智能计算中心', '超算中心'] },
{ id: 'lv3_1_1_2', name: 'AI关键组件', concept_count: 24, concepts: ['HBM', 'PCB', '光通信', '存储芯片', 'CPO', '光模块', '铜连接', '高速背板'] },
{ id: 'lv3_1_1_3', name: 'AI配套设施', concept_count: 12, concepts: ['数据中心', '液冷', '电力设备', 'UPS', 'IDC服务', '边缘计算', 'AI电源'] }
]
},
{
id: 'lv2_1_2',
name: 'AI模型与软件',
concept_count: 18,
concepts: ['DeepSeek', 'KIMI', 'SORA概念', '国产大模型', 'ChatGPT', 'Claude', '文心一言', '通义千问', 'Gemini概念', 'AI推理']
},
{
id: 'lv2_1_3',
name: 'AI应用',
concept_count: 28,
children: [
{ id: 'lv3_1_3_1', name: '智能体与陪伴', concept_count: 11, concepts: ['AI伴侣', 'AI智能体', 'AI陪伴', 'AI助手', '数字人', 'AI语音', 'AI社交'] },
{ id: 'lv3_1_3_2', name: '行业应用', concept_count: 17, concepts: ['AI编程', '低代码', 'AI教育', 'AI医疗', 'AI金融', 'AI制造', 'AI安防', 'AI营销', 'AI设计'] }
]
}
]
},
{
id: 'lv1_2',
name: '半导体',
concept_count: 65,
children: [
{
id: 'lv2_2_1',
name: '半导体设备',
concept_count: 18,
children: [
{ id: 'lv3_2_1_1', name: '前道设备', concept_count: 10, concepts: ['光刻机', '刻蚀设备', '薄膜沉积', '离子注入', 'CMP设备', '清洗设备'] },
{ id: 'lv3_2_1_2', name: '后道设备', concept_count: 8, concepts: ['划片机', '键合设备', '测试设备', '封装设备', 'AOI检测'] }
]
},
{
id: 'lv2_2_2',
name: '半导体材料',
concept_count: 15,
concepts: ['光刻胶', '半导体材料', '石英砂', '硅片', '电子特气', '靶材', 'CMP抛光液', '湿电子化学品', '掩模版']
},
{
id: 'lv2_2_3',
name: '芯片设计与制造',
concept_count: 22,
children: [
{ id: 'lv3_2_3_1', name: '数字芯片', concept_count: 12, concepts: ['CPU', 'GPU', 'FPGA', 'ASIC', 'MCU', 'DSP', 'NPU芯片'] },
{ id: 'lv3_2_3_2', name: '模拟芯片', concept_count: 10, concepts: ['电源管理芯片', '驱动芯片', '传感器芯片', '射频芯片', '功率半导体', '碳化硅', '氮化镓'] }
]
},
{ id: 'lv2_2_4', name: '先进封装', concept_count: 10, concepts: ['玻璃基板', '半导体封测', 'Chiplet', 'CoWoS', 'SiP', '3D封装', '扇出封装'] }
]
},
{
id: 'lv1_3',
name: '机器人',
concept_count: 52,
children: [
{
id: 'lv2_3_1',
name: '人形机器人整机',
concept_count: 20,
children: [
{ id: 'lv3_3_1_1', name: '整机厂商', concept_count: 12, concepts: ['特斯拉机器人', '人形机器人', '智元机器人', '优必选', '小米机器人', '华为机器人', '波士顿动力概念'] },
{ id: 'lv3_3_1_2', name: '解决方案', concept_count: 8, concepts: ['具身智能', '机器人操作系统', '多模态AI', '机器人仿真'] }
]
},
{
id: 'lv2_3_2',
name: '机器人核心零部件',
concept_count: 20,
concepts: ['滚柱丝杆', '电子皮肤', '轴向磁通电机', '谐波减速器', '行星减速器', '伺服电机', '编码器', '力矩传感器', '六维力传感器', '灵巧手', '机器人关节']
},
{ id: 'lv2_3_3', name: '其他类型机器人', concept_count: 12, concepts: ['工业机器人', '机器狗', '外骨骼机器人', '协作机器人', '手术机器人', '服务机器人', '物流机器人', '农业机器人'] }
]
},
{
id: 'lv1_4',
name: '消费电子',
concept_count: 48,
children: [
{ id: 'lv2_4_1', name: '智能终端', concept_count: 12, concepts: ['AI PC', 'AI手机', '折叠屏', '卫星通信手机', '智能手表', '智能耳机', '智能音箱', '平板电脑'] },
{
id: 'lv2_4_2',
name: 'XR与空间计算',
concept_count: 18,
children: [
{ id: 'lv3_4_2_1', name: 'XR硬件', concept_count: 10, concepts: ['AR眼镜', 'MR', '智能眼镜', 'VR头显', 'Apple Vision Pro概念', 'Meta Quest概念'] },
{ id: 'lv3_4_2_2', name: 'XR软件与内容', concept_count: 8, concepts: ['XR内容', '空间计算', '3D引擎', 'XR社交', 'XR游戏'] }
]
},
{ id: 'lv2_4_3', name: '华为产业链', concept_count: 18, concepts: ['华为Mate70', '鸿蒙', '华为昇腾', '华为汽车', '华为海思', '华为云', '华为手机', '华为概念', '麒麟芯片'] }
]
},
{
id: 'lv1_5',
name: '智能驾驶与汽车',
concept_count: 45,
children: [
{
id: 'lv2_5_1',
name: '自动驾驶解决方案',
concept_count: 18,
children: [
{ id: 'lv3_5_1_1', name: '整体方案', concept_count: 10, concepts: ['Robotaxi', '无人驾驶', '特斯拉FSD', 'L4自动驾驶', '萝卜快跑', '百度Apollo'] },
{ id: 'lv3_5_1_2', name: '核心部件', concept_count: 8, concepts: ['自动驾驶芯片', '激光雷达', '毫米波雷达', '车载摄像头', '域控制器'] }
]
},
{ id: 'lv2_5_2', name: '智能汽车产业链', concept_count: 18, concepts: ['比亚迪产业链', '小米汽车产业链', '特斯拉产业链', '理想产业链', '蔚来产业链', '小鹏产业链', '新能源汽车', '智能座舱', '汽车电子'] },
{ id: 'lv2_5_3', name: '车路协同', concept_count: 9, concepts: ['车路云一体化', '车路协同', 'V2X', '智能交通', '高精地图', '车联网'] }
]
},
{
id: 'lv1_6',
name: '新能源与电力',
concept_count: 62,
children: [
{
id: 'lv2_6_1',
name: '新型电池技术',
concept_count: 22,
children: [
{ id: 'lv3_6_1_1', name: '电池类型', concept_count: 12, concepts: ['固态电池', '钠离子电池', '锂电池', '磷酸铁锂', '三元锂电池', '刀片电池', '4680电池'] },
{ id: 'lv3_6_1_2', name: '电池材料', concept_count: 10, concepts: ['硅基负极', '正极材料', '负极材料', '电解液', '隔膜', '锂矿', '钠矿'] }
]
},
{ id: 'lv2_6_2', name: '电力设备与电网', concept_count: 24, concepts: ['电力', '变压器出海', '燃料电池', '特高压', '智能电网', '配电网', '虚拟电厂', '储能', '抽水蓄能', '电力物联网', '充电桩'] },
{ id: 'lv2_6_3', name: '清洁能源', concept_count: 16, concepts: ['光伏', '核电', '可控核聚变', '风电', '海上风电', '氢能源', '绿电', '碳中和', 'CCER'] }
]
},
{
id: 'lv1_7',
name: '空天经济',
concept_count: 38,
children: [
{
id: 'lv2_7_1',
name: '低空经济',
concept_count: 20,
children: [
{ id: 'lv3_7_1_1', name: '飞行器', concept_count: 12, concepts: ['低空经济', 'eVTOL', '飞行汽车', '无人机', '电动垂直起降', '载人飞行器', '物流无人机'] },
{ id: 'lv3_7_1_2', name: '配套设施', concept_count: 8, concepts: ['低空空域', '通用航空', '无人机反制', '低空雷达', '飞行管控'] }
]
},
{ id: 'lv2_7_2', name: '商业航天', concept_count: 18, concepts: ['卫星互联网', '商业航天', '北斗导航', '星链概念', '火箭发射', '卫星制造', '遥感卫星', '通信卫星', '空间站', '太空旅游'] }
]
},
{
id: 'lv1_8',
name: '国防军工',
concept_count: 35,
children: [
{ id: 'lv2_8_1', name: '无人作战与信息化', concept_count: 14, concepts: ['AI军工', '无人机蜂群', '军工信息化', '无人作战', '军用无人机', '军用机器人', '电子战', '军用芯片'] },
{ id: 'lv2_8_2', name: '海军装备', concept_count: 12, concepts: ['国产航母', '电磁弹射', '舰艇', '潜艇', '海军武器', '舰载机', '军船', '海洋装备'] },
{ id: 'lv2_8_3', name: '军贸出海', concept_count: 9, concepts: ['军贸', '巴黎航展', '武器出口', '国际军贸', '军工出海', '航展概念'] }
]
},
{
id: 'lv1_9',
name: '政策与主题',
concept_count: 42,
children: [
{ id: 'lv2_9_1', name: '国家战略', concept_count: 22, concepts: ['一带一路', '国产替代', '自主可控', '信创', '数字经济', '数据要素', '东数西算', '新基建', '乡村振兴', '共同富裕', '双循环'] },
{ id: 'lv2_9_2', name: '区域发展', concept_count: 20, concepts: ['粤港澳大湾区', '长三角一体化', '京津冀协同', '成渝经济圈', '海南自贸港', '雄安新区', '西部大开发', '中部崛起'] }
]
},
{
id: 'lv1_10',
name: '周期与材料',
concept_count: 35,
children: [
{ id: 'lv2_10_1', name: '有色金属', concept_count: 18, concepts: ['黄金', '白银', '铜', '铝', '稀土', '锂', '钴', '镍', '锡', '锌', '小金属'] },
{ id: 'lv2_10_2', name: '化工材料', concept_count: 17, concepts: ['氟化工', '磷化工', '钛白粉', '碳纤维', '石墨烯', '复合材料', '新材料', '高分子材料'] }
]
},
{
id: 'lv1_11',
name: '大消费',
concept_count: 45,
children: [
{ id: 'lv2_11_1', name: '食品饮料', concept_count: 22, concepts: ['白酒', '啤酒', '乳业', '预制菜', '零食', '调味品', '饮料', '食品加工', '餐饮', '咖啡茶饮'] },
{ id: 'lv2_11_2', name: '消费服务', concept_count: 23, concepts: ['免税', '旅游', '酒店', '航空', '电商', '直播带货', '新零售', '社区团购', '跨境电商', '本地生活'] }
]
},
{
id: 'lv1_12',
name: '数字经济与金融科技',
concept_count: 38,
children: [
{ id: 'lv2_12_1', name: '金融科技', concept_count: 20, concepts: ['数字货币', '数字人民币', '区块链', 'Web3', '金融IT', '征信', '保险科技', '券商金融科技'] },
{ id: 'lv2_12_2', name: '数字化转型', concept_count: 18, concepts: ['云计算', '大数据', '物联网', '5G', '6G', '数字孪生', '元宇宙', '工业互联网', 'SaaS'] }
]
},
{
id: 'lv1_13',
name: '医药健康',
concept_count: 55,
children: [
{ id: 'lv2_13_1', name: '创新药', concept_count: 25, concepts: ['创新药', 'CXO', 'ADC', '减肥药', 'GLP-1', 'CAR-T', '细胞治疗', '基因治疗', 'mRNA', 'PROTAC'] },
{ id: 'lv2_13_2', name: '医疗器械', concept_count: 18, concepts: ['医疗器械', '高值耗材', '医疗影像', '手术机器人', '康复器械', 'IVD', '医美设备', '眼科器械'] },
{ id: 'lv2_13_3', name: '中医药', concept_count: 12, concepts: ['中药', '中药创新药', '中医诊疗', '中药配方颗粒', '道地药材'] }
]
},
{
id: 'lv1_14',
name: '前沿科技',
concept_count: 28,
children: [
{ id: 'lv2_14_1', name: '量子科技', concept_count: 14, concepts: ['量子计算', '量子通信', '量子芯片', '量子加密', '量子传感', '量子软件'] },
{ id: 'lv2_14_2', name: '脑机接口', concept_count: 14, concepts: ['脑机接口', 'Neuralink概念', '神经科技', '脑科学', '人脑芯片', '神经调控'] }
]
},
{
id: 'lv1_15',
name: '全球宏观与贸易',
concept_count: 25,
children: [
{ id: 'lv2_8_1', name: '无人作战与信息化', concept_count: 10, concepts: ['AI军工', '无人机蜂群', '军工信息化'] },
{ id: 'lv2_8_2', name: '海军装备', concept_count: 8, concepts: ['国产航母', '电磁弹射'] },
{ id: 'lv2_8_3', name: '军贸出海', concept_count: 7, concepts: ['军贸', '巴黎航展'] }
{ id: 'lv2_15_1', name: '国际贸易', concept_count: 15, concepts: ['跨境电商', '出口', '贸易摩擦', '人民币国际化', '中美贸易', '中欧贸易', '东盟贸易'] },
{ id: 'lv2_15_2', name: '宏观主题', concept_count: 10, concepts: ['美联储加息', '美债', '汇率', '通胀', '衰退预期', '地缘政治'] }
]
}
];
@@ -737,7 +1045,98 @@ export const conceptHandlers = [
});
}),
// 获取层级涨跌幅数据(实时价格
// 获取层级涨跌幅数据(硬编码 URL - 开发环境
http.get('http://111.198.58.126:16801/hierarchy/price', async ({ request }) => {
await delay(200);
const url = new URL(request.url);
const tradeDate = url.searchParams.get('trade_date');
console.log('[Mock Concept] 获取层级涨跌幅数据 (硬编码URL):', { tradeDate });
// 模拟 lv1 层级涨跌幅数据
const lv1_concepts = [
{ concept_name: '人工智能', avg_change_pct: 3.56, stock_count: 245 },
{ concept_name: '半导体', avg_change_pct: 2.12, stock_count: 156 },
{ concept_name: '机器人', avg_change_pct: 4.28, stock_count: 128 },
{ concept_name: '消费电子', avg_change_pct: 1.45, stock_count: 98 },
{ concept_name: '智能驾驶与汽车', avg_change_pct: 2.89, stock_count: 112 },
{ concept_name: '新能源与电力', avg_change_pct: -0.56, stock_count: 186 },
{ concept_name: '空天经济', avg_change_pct: 3.12, stock_count: 76 },
{ concept_name: '国防军工', avg_change_pct: 1.78, stock_count: 89 }
];
// 模拟 lv2 层级涨跌幅数据
const lv2_concepts = [
{ concept_name: 'AI基础设施', avg_change_pct: 4.12, stock_count: 85 },
{ concept_name: 'AI模型与软件', avg_change_pct: 5.67, stock_count: 42 },
{ concept_name: 'AI应用', avg_change_pct: 2.34, stock_count: 65 },
{ concept_name: '半导体设备', avg_change_pct: 3.21, stock_count: 38 },
{ concept_name: '半导体材料', avg_change_pct: 1.89, stock_count: 32 },
{ concept_name: '芯片设计与制造', avg_change_pct: 2.45, stock_count: 56 },
{ concept_name: '先进封装', avg_change_pct: 1.23, stock_count: 22 },
{ concept_name: '人形机器人整机', avg_change_pct: 5.89, stock_count: 45 },
{ concept_name: '机器人核心零部件', avg_change_pct: 3.45, stock_count: 52 },
{ concept_name: '其他类型机器人', avg_change_pct: 2.12, stock_count: 31 },
{ concept_name: '智能终端', avg_change_pct: 1.78, stock_count: 28 },
{ concept_name: 'XR与空间计算', avg_change_pct: 2.56, stock_count: 36 },
{ concept_name: '华为产业链', avg_change_pct: 0.89, stock_count: 48 },
{ concept_name: '自动驾驶解决方案', avg_change_pct: 4.23, stock_count: 35 },
{ concept_name: '智能汽车产业链', avg_change_pct: 2.45, stock_count: 52 },
{ concept_name: '车路协同', avg_change_pct: 1.56, stock_count: 25 },
{ concept_name: '新型电池技术', avg_change_pct: 0.67, stock_count: 62 },
{ concept_name: '电力设备与电网', avg_change_pct: -1.23, stock_count: 78 },
{ concept_name: '清洁能源', avg_change_pct: -0.45, stock_count: 46 },
{ concept_name: '低空经济', avg_change_pct: 4.56, stock_count: 42 },
{ concept_name: '商业航天', avg_change_pct: 1.89, stock_count: 34 },
{ concept_name: '无人作战与信息化', avg_change_pct: 2.34, stock_count: 28 },
{ concept_name: '海军装备', avg_change_pct: 1.45, stock_count: 32 },
{ concept_name: '军贸出海', avg_change_pct: 1.12, stock_count: 18 }
];
// 模拟 lv3 层级涨跌幅数据
const lv3_concepts = [
{ concept_name: 'AI算力硬件', avg_change_pct: 5.23, stock_count: 32 },
{ concept_name: 'AI关键组件', avg_change_pct: 3.89, stock_count: 45 },
{ concept_name: 'AI配套设施', avg_change_pct: 2.67, stock_count: 28 },
{ concept_name: '智能体与陪伴', avg_change_pct: 3.12, stock_count: 24 },
{ concept_name: '行业应用', avg_change_pct: 1.56, stock_count: 18 }
];
// 模拟叶子概念涨跌幅数据
const leaf_concepts = [
{ concept_name: 'AI芯片', avg_change_pct: 6.78, stock_count: 12, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI算力硬件' },
{ concept_name: 'GPU概念股', avg_change_pct: 5.45, stock_count: 8, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI算力硬件' },
{ concept_name: 'HBM', avg_change_pct: 8.12, stock_count: 10, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI关键组件' },
{ concept_name: 'CPO', avg_change_pct: 9.34, stock_count: 8, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI关键组件' },
{ concept_name: '液冷', avg_change_pct: 6.78, stock_count: 12, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI配套设施' },
{ concept_name: 'DeepSeek', avg_change_pct: 12.34, stock_count: 15, lv1: '人工智能', lv2: 'AI模型与软件' },
{ concept_name: 'KIMI', avg_change_pct: 8.56, stock_count: 12, lv1: '人工智能', lv2: 'AI模型与软件' },
{ concept_name: '特斯拉机器人', avg_change_pct: 8.45, stock_count: 18, lv1: '机器人', lv2: '人形机器人整机' },
{ concept_name: '人形机器人', avg_change_pct: 7.23, stock_count: 25, lv1: '机器人', lv2: '人形机器人整机' },
{ concept_name: '低空经济', avg_change_pct: 6.78, stock_count: 22, lv1: '空天经济', lv2: '低空经济' },
{ concept_name: 'eVTOL', avg_change_pct: 7.89, stock_count: 15, lv1: '空天经济', lv2: '低空经济' },
{ concept_name: '光刻机', avg_change_pct: 5.67, stock_count: 10, lv1: '半导体', lv2: '半导体设备' },
{ concept_name: 'Chiplet', avg_change_pct: 4.56, stock_count: 14, lv1: '半导体', lv2: '先进封装' },
{ concept_name: '固态电池', avg_change_pct: 3.45, stock_count: 18, lv1: '新能源与电力', lv2: '新型电池技术' },
{ concept_name: 'Robotaxi', avg_change_pct: 5.67, stock_count: 14, lv1: '智能驾驶与汽车', lv2: '自动驾驶解决方案' },
{ concept_name: 'AR眼镜', avg_change_pct: 4.56, stock_count: 16, lv1: '消费电子', lv2: 'XR与空间计算' }
];
const today = tradeDate ? new Date(tradeDate) : new Date();
const tradeDateStr = today.toISOString().split('T')[0];
return HttpResponse.json({
trade_date: tradeDateStr,
lv1_concepts,
lv2_concepts,
lv3_concepts,
leaf_concepts,
update_time: new Date().toISOString()
});
}),
// 获取层级涨跌幅数据(实时价格)- 完整版本,包含 leaf_concepts
http.get('/concept-api/hierarchy/price', async ({ request }) => {
await delay(200);
@@ -755,7 +1154,14 @@ export const conceptHandlers = [
{ concept_name: '智能驾驶与汽车', avg_change_pct: 2.89, stock_count: 112 },
{ concept_name: '新能源与电力', avg_change_pct: -0.56, stock_count: 186 },
{ concept_name: '空天经济', avg_change_pct: 3.12, stock_count: 76 },
{ concept_name: '国防军工', avg_change_pct: 1.78, stock_count: 89 }
{ concept_name: '国防军工', avg_change_pct: 1.78, stock_count: 89 },
{ concept_name: '政策与主题', avg_change_pct: 1.23, stock_count: 95 },
{ concept_name: '周期与材料', avg_change_pct: -0.89, stock_count: 82 },
{ concept_name: '大消费', avg_change_pct: 0.56, stock_count: 115 },
{ concept_name: '数字经济与金融科技', avg_change_pct: 2.34, stock_count: 88 },
{ concept_name: '医药健康', avg_change_pct: -1.23, stock_count: 142 },
{ concept_name: '前沿科技', avg_change_pct: 4.67, stock_count: 56 },
{ concept_name: '全球宏观与贸易', avg_change_pct: 0.12, stock_count: 48 }
];
// 模拟 lv2 层级涨跌幅数据
@@ -791,7 +1197,29 @@ export const conceptHandlers = [
// 国防军工下的 lv2
{ concept_name: '无人作战与信息化', avg_change_pct: 2.34, stock_count: 28 },
{ concept_name: '海军装备', avg_change_pct: 1.45, stock_count: 32 },
{ concept_name: '军贸出海', avg_change_pct: 1.12, stock_count: 18 }
{ concept_name: '军贸出海', avg_change_pct: 1.12, stock_count: 18 },
// 政策与主题下的 lv2
{ concept_name: '国家战略', avg_change_pct: 1.56, stock_count: 52 },
{ concept_name: '区域发展', avg_change_pct: 0.89, stock_count: 43 },
// 周期与材料下的 lv2
{ concept_name: '有色金属', avg_change_pct: -1.23, stock_count: 45 },
{ concept_name: '化工材料', avg_change_pct: -0.56, stock_count: 37 },
// 大消费下的 lv2
{ concept_name: '食品饮料', avg_change_pct: 0.78, stock_count: 58 },
{ concept_name: '消费服务', avg_change_pct: 0.34, stock_count: 57 },
// 数字经济与金融科技下的 lv2
{ concept_name: '金融科技', avg_change_pct: 2.89, stock_count: 46 },
{ concept_name: '数字化转型', avg_change_pct: 1.78, stock_count: 42 },
// 医药健康下的 lv2
{ concept_name: '创新药', avg_change_pct: -1.56, stock_count: 65 },
{ concept_name: '医疗器械', avg_change_pct: -0.89, stock_count: 48 },
{ concept_name: '中医药', avg_change_pct: -1.12, stock_count: 29 },
// 前沿科技下的 lv2
{ concept_name: '量子科技', avg_change_pct: 5.23, stock_count: 28 },
{ concept_name: '脑机接口', avg_change_pct: 4.12, stock_count: 28 },
// 全球宏观与贸易下的 lv2
{ concept_name: '国际贸易', avg_change_pct: 0.23, stock_count: 32 },
{ concept_name: '宏观主题', avg_change_pct: -0.01, stock_count: 16 }
];
// 模拟 lv3 层级涨跌幅数据
@@ -802,7 +1230,219 @@ export const conceptHandlers = [
{ concept_name: 'AI配套设施', avg_change_pct: 2.67, stock_count: 28 },
// AI应用下的 lv3
{ concept_name: '智能体与陪伴', avg_change_pct: 3.12, stock_count: 24 },
{ concept_name: '行业应用', avg_change_pct: 1.56, stock_count: 18 }
{ concept_name: '行业应用', avg_change_pct: 1.56, stock_count: 18 },
// 半导体设备下的 lv3
{ concept_name: '前道设备', avg_change_pct: 3.89, stock_count: 22 },
{ concept_name: '后道设备', avg_change_pct: 2.45, stock_count: 16 },
// 芯片设计与制造下的 lv3
{ concept_name: '数字芯片', avg_change_pct: 2.78, stock_count: 32 },
{ concept_name: '模拟芯片', avg_change_pct: 2.12, stock_count: 24 },
// 人形机器人下的 lv3
{ concept_name: '整机厂商', avg_change_pct: 6.78, stock_count: 25 },
{ concept_name: '解决方案', avg_change_pct: 4.56, stock_count: 20 },
// XR与空间计算下的 lv3
{ concept_name: 'XR硬件', avg_change_pct: 3.12, stock_count: 22 },
{ concept_name: 'XR软件与内容', avg_change_pct: 1.89, stock_count: 14 },
// 自动驾驶解决方案下的 lv3
{ concept_name: '整体方案', avg_change_pct: 5.12, stock_count: 18 },
{ concept_name: '核心部件', avg_change_pct: 3.34, stock_count: 17 },
// 新型电池技术下的 lv3
{ concept_name: '电池类型', avg_change_pct: 1.23, stock_count: 35 },
{ concept_name: '电池材料', avg_change_pct: 0.12, stock_count: 27 },
// 低空经济下的 lv3
{ concept_name: '飞行器', avg_change_pct: 5.67, stock_count: 26 },
{ concept_name: '配套设施', avg_change_pct: 3.12, stock_count: 16 }
];
// 模拟叶子概念涨跌幅数据 (leaf_concepts) - 这是最细粒度的概念数据
const leaf_concepts = [
// 人工智能 - AI基础设施 - AI算力硬件
{ concept_name: 'AI芯片', avg_change_pct: 6.78, stock_count: 12, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI算力硬件' },
{ concept_name: 'GPU概念股', avg_change_pct: 5.45, stock_count: 8, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI算力硬件' },
{ concept_name: '服务器', avg_change_pct: 4.23, stock_count: 15, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI算力硬件' },
{ concept_name: 'AI一体机', avg_change_pct: 5.12, stock_count: 6, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI算力硬件' },
{ concept_name: '算力租赁', avg_change_pct: 3.89, stock_count: 8, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI算力硬件' },
{ concept_name: 'NPU', avg_change_pct: 7.23, stock_count: 5, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI算力硬件' },
{ concept_name: '智能计算中心', avg_change_pct: 4.56, stock_count: 9, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI算力硬件' },
{ concept_name: '超算中心', avg_change_pct: 3.12, stock_count: 4, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI算力硬件' },
// AI关键组件
{ concept_name: 'HBM', avg_change_pct: 8.12, stock_count: 10, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI关键组件' },
{ concept_name: 'PCB', avg_change_pct: 2.34, stock_count: 18, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI关键组件' },
{ concept_name: '光通信', avg_change_pct: 4.56, stock_count: 14, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI关键组件' },
{ concept_name: '存储芯片', avg_change_pct: 3.78, stock_count: 12, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI关键组件' },
{ concept_name: 'CPO', avg_change_pct: 9.34, stock_count: 8, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI关键组件' },
{ concept_name: '光模块', avg_change_pct: 5.67, stock_count: 11, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI关键组件' },
{ concept_name: '铜连接', avg_change_pct: 3.45, stock_count: 9, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI关键组件' },
{ concept_name: '高速背板', avg_change_pct: 2.89, stock_count: 6, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI关键组件' },
// AI配套设施
{ concept_name: '数据中心', avg_change_pct: 3.12, stock_count: 16, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI配套设施' },
{ concept_name: '液冷', avg_change_pct: 6.78, stock_count: 12, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI配套设施' },
{ concept_name: '电力设备', avg_change_pct: 1.23, stock_count: 22, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI配套设施' },
{ concept_name: 'UPS', avg_change_pct: 2.45, stock_count: 8, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI配套设施' },
{ concept_name: 'IDC服务', avg_change_pct: 1.89, stock_count: 10, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI配套设施' },
{ concept_name: '边缘计算', avg_change_pct: 2.67, stock_count: 9, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI配套设施' },
{ concept_name: 'AI电源', avg_change_pct: 4.12, stock_count: 7, lv1: '人工智能', lv2: 'AI基础设施', lv3: 'AI配套设施' },
// AI模型与软件
{ concept_name: 'DeepSeek', avg_change_pct: 12.34, stock_count: 15, lv1: '人工智能', lv2: 'AI模型与软件' },
{ concept_name: 'KIMI', avg_change_pct: 8.56, stock_count: 12, lv1: '人工智能', lv2: 'AI模型与软件' },
{ concept_name: 'SORA概念', avg_change_pct: 6.78, stock_count: 10, lv1: '人工智能', lv2: 'AI模型与软件' },
{ concept_name: '国产大模型', avg_change_pct: 5.45, stock_count: 18, lv1: '人工智能', lv2: 'AI模型与软件' },
{ concept_name: 'ChatGPT', avg_change_pct: 4.23, stock_count: 14, lv1: '人工智能', lv2: 'AI模型与软件' },
{ concept_name: 'Claude', avg_change_pct: 3.89, stock_count: 8, lv1: '人工智能', lv2: 'AI模型与软件' },
{ concept_name: '文心一言', avg_change_pct: 5.12, stock_count: 11, lv1: '人工智能', lv2: 'AI模型与软件' },
{ concept_name: '通义千问', avg_change_pct: 4.67, stock_count: 9, lv1: '人工智能', lv2: 'AI模型与软件' },
{ concept_name: 'Gemini概念', avg_change_pct: 3.45, stock_count: 6, lv1: '人工智能', lv2: 'AI模型与软件' },
{ concept_name: 'AI推理', avg_change_pct: 4.89, stock_count: 13, lv1: '人工智能', lv2: 'AI模型与软件' },
// AI应用 - 智能体与陪伴
{ concept_name: 'AI伴侣', avg_change_pct: 4.56, stock_count: 8, lv1: '人工智能', lv2: 'AI应用', lv3: '智能体与陪伴' },
{ concept_name: 'AI智能体', avg_change_pct: 5.78, stock_count: 12, lv1: '人工智能', lv2: 'AI应用', lv3: '智能体与陪伴' },
{ concept_name: 'AI陪伴', avg_change_pct: 3.23, stock_count: 6, lv1: '人工智能', lv2: 'AI应用', lv3: '智能体与陪伴' },
{ concept_name: 'AI助手', avg_change_pct: 2.89, stock_count: 10, lv1: '人工智能', lv2: 'AI应用', lv3: '智能体与陪伴' },
{ concept_name: '数字人', avg_change_pct: 4.12, stock_count: 14, lv1: '人工智能', lv2: 'AI应用', lv3: '智能体与陪伴' },
{ concept_name: 'AI语音', avg_change_pct: 1.67, stock_count: 9, lv1: '人工智能', lv2: 'AI应用', lv3: '智能体与陪伴' },
{ concept_name: 'AI社交', avg_change_pct: 2.34, stock_count: 5, lv1: '人工智能', lv2: 'AI应用', lv3: '智能体与陪伴' },
// AI应用 - 行业应用
{ concept_name: 'AI编程', avg_change_pct: 3.45, stock_count: 11, lv1: '人工智能', lv2: 'AI应用', lv3: '行业应用' },
{ concept_name: '低代码', avg_change_pct: 1.89, stock_count: 8, lv1: '人工智能', lv2: 'AI应用', lv3: '行业应用' },
{ concept_name: 'AI教育', avg_change_pct: 2.12, stock_count: 12, lv1: '人工智能', lv2: 'AI应用', lv3: '行业应用' },
{ concept_name: 'AI医疗', avg_change_pct: 0.78, stock_count: 15, lv1: '人工智能', lv2: 'AI应用', lv3: '行业应用' },
{ concept_name: 'AI金融', avg_change_pct: 1.56, stock_count: 10, lv1: '人工智能', lv2: 'AI应用', lv3: '行业应用' },
{ concept_name: 'AI制造', avg_change_pct: 1.23, stock_count: 8, lv1: '人工智能', lv2: 'AI应用', lv3: '行业应用' },
{ concept_name: 'AI安防', avg_change_pct: 0.89, stock_count: 11, lv1: '人工智能', lv2: 'AI应用', lv3: '行业应用' },
{ concept_name: 'AI营销', avg_change_pct: 2.34, stock_count: 7, lv1: '人工智能', lv2: 'AI应用', lv3: '行业应用' },
{ concept_name: 'AI设计', avg_change_pct: 1.67, stock_count: 6, lv1: '人工智能', lv2: 'AI应用', lv3: '行业应用' },
// 机器人相关叶子概念
{ concept_name: '特斯拉机器人', avg_change_pct: 8.45, stock_count: 18, lv1: '机器人', lv2: '人形机器人整机', lv3: '整机厂商' },
{ concept_name: '人形机器人', avg_change_pct: 7.23, stock_count: 25, lv1: '机器人', lv2: '人形机器人整机', lv3: '整机厂商' },
{ concept_name: '智元机器人', avg_change_pct: 6.12, stock_count: 10, lv1: '机器人', lv2: '人形机器人整机', lv3: '整机厂商' },
{ concept_name: '优必选', avg_change_pct: 5.78, stock_count: 8, lv1: '机器人', lv2: '人形机器人整机', lv3: '整机厂商' },
{ concept_name: '滚柱丝杆', avg_change_pct: 4.56, stock_count: 12, lv1: '机器人', lv2: '机器人核心零部件' },
{ concept_name: '电子皮肤', avg_change_pct: 5.89, stock_count: 8, lv1: '机器人', lv2: '机器人核心零部件' },
{ concept_name: '轴向磁通电机', avg_change_pct: 3.78, stock_count: 6, lv1: '机器人', lv2: '机器人核心零部件' },
{ concept_name: '谐波减速器', avg_change_pct: 2.89, stock_count: 10, lv1: '机器人', lv2: '机器人核心零部件' },
{ concept_name: '行星减速器', avg_change_pct: 2.45, stock_count: 9, lv1: '机器人', lv2: '机器人核心零部件' },
{ concept_name: '伺服电机', avg_change_pct: 3.12, stock_count: 14, lv1: '机器人', lv2: '机器人核心零部件' },
{ concept_name: '六维力传感器', avg_change_pct: 4.23, stock_count: 7, lv1: '机器人', lv2: '机器人核心零部件' },
{ concept_name: '灵巧手', avg_change_pct: 5.12, stock_count: 6, lv1: '机器人', lv2: '机器人核心零部件' },
// 低空经济相关叶子概念
{ concept_name: '低空经济', avg_change_pct: 6.78, stock_count: 22, lv1: '空天经济', lv2: '低空经济', lv3: '飞行器' },
{ concept_name: 'eVTOL', avg_change_pct: 7.89, stock_count: 15, lv1: '空天经济', lv2: '低空经济', lv3: '飞行器' },
{ concept_name: '飞行汽车', avg_change_pct: 5.45, stock_count: 12, lv1: '空天经济', lv2: '低空经济', lv3: '飞行器' },
{ concept_name: '无人机', avg_change_pct: 4.23, stock_count: 18, lv1: '空天经济', lv2: '低空经济', lv3: '飞行器' },
{ concept_name: '电动垂直起降', avg_change_pct: 6.12, stock_count: 10, lv1: '空天经济', lv2: '低空经济', lv3: '飞行器' },
{ concept_name: '卫星互联网', avg_change_pct: 3.45, stock_count: 16, lv1: '空天经济', lv2: '商业航天' },
{ concept_name: '商业航天', avg_change_pct: 2.89, stock_count: 14, lv1: '空天经济', lv2: '商业航天' },
{ concept_name: '北斗导航', avg_change_pct: 1.56, stock_count: 20, lv1: '空天经济', lv2: '商业航天' },
{ concept_name: '星链概念', avg_change_pct: 4.12, stock_count: 8, lv1: '空天经济', lv2: '商业航天' },
// 半导体相关叶子概念
{ concept_name: '光刻机', avg_change_pct: 5.67, stock_count: 10, lv1: '半导体', lv2: '半导体设备', lv3: '前道设备' },
{ concept_name: '刻蚀设备', avg_change_pct: 4.23, stock_count: 8, lv1: '半导体', lv2: '半导体设备', lv3: '前道设备' },
{ concept_name: '薄膜沉积', avg_change_pct: 3.89, stock_count: 7, lv1: '半导体', lv2: '半导体设备', lv3: '前道设备' },
{ concept_name: '光刻胶', avg_change_pct: 2.34, stock_count: 12, lv1: '半导体', lv2: '半导体材料' },
{ concept_name: '半导体材料', avg_change_pct: 1.89, stock_count: 18, lv1: '半导体', lv2: '半导体材料' },
{ concept_name: '硅片', avg_change_pct: 1.23, stock_count: 10, lv1: '半导体', lv2: '半导体材料' },
{ concept_name: '电子特气', avg_change_pct: 2.56, stock_count: 8, lv1: '半导体', lv2: '半导体材料' },
{ concept_name: 'Chiplet', avg_change_pct: 4.56, stock_count: 14, lv1: '半导体', lv2: '先进封装' },
{ concept_name: 'CoWoS', avg_change_pct: 5.12, stock_count: 10, lv1: '半导体', lv2: '先进封装' },
{ concept_name: '玻璃基板', avg_change_pct: 3.78, stock_count: 8, lv1: '半导体', lv2: '先进封装' },
// 新能源相关叶子概念
{ concept_name: '固态电池', avg_change_pct: 3.45, stock_count: 18, lv1: '新能源与电力', lv2: '新型电池技术', lv3: '电池类型' },
{ concept_name: '钠离子电池', avg_change_pct: 2.12, stock_count: 14, lv1: '新能源与电力', lv2: '新型电池技术', lv3: '电池类型' },
{ concept_name: '锂电池', avg_change_pct: 0.89, stock_count: 25, lv1: '新能源与电力', lv2: '新型电池技术', lv3: '电池类型' },
{ concept_name: '磷酸铁锂', avg_change_pct: 0.56, stock_count: 16, lv1: '新能源与电力', lv2: '新型电池技术', lv3: '电池类型' },
{ concept_name: '硅基负极', avg_change_pct: 1.78, stock_count: 10, lv1: '新能源与电力', lv2: '新型电池技术', lv3: '电池材料' },
{ concept_name: '电解液', avg_change_pct: -0.34, stock_count: 12, lv1: '新能源与电力', lv2: '新型电池技术', lv3: '电池材料' },
{ concept_name: '光伏', avg_change_pct: -1.23, stock_count: 28, lv1: '新能源与电力', lv2: '清洁能源' },
{ concept_name: '核电', avg_change_pct: 0.56, stock_count: 14, lv1: '新能源与电力', lv2: '清洁能源' },
{ concept_name: '可控核聚变', avg_change_pct: 2.89, stock_count: 8, lv1: '新能源与电力', lv2: '清洁能源' },
{ concept_name: '风电', avg_change_pct: -0.89, stock_count: 20, lv1: '新能源与电力', lv2: '清洁能源' },
{ concept_name: '储能', avg_change_pct: -0.45, stock_count: 22, lv1: '新能源与电力', lv2: '电力设备与电网' },
{ concept_name: '充电桩', avg_change_pct: 1.23, stock_count: 16, lv1: '新能源与电力', lv2: '电力设备与电网' },
{ concept_name: '特高压', avg_change_pct: -1.56, stock_count: 12, lv1: '新能源与电力', lv2: '电力设备与电网' },
// 前沿科技叶子概念
{ concept_name: '量子计算', avg_change_pct: 6.78, stock_count: 12, lv1: '前沿科技', lv2: '量子科技' },
{ concept_name: '量子通信', avg_change_pct: 4.56, stock_count: 10, lv1: '前沿科技', lv2: '量子科技' },
{ concept_name: '量子芯片', avg_change_pct: 5.23, stock_count: 8, lv1: '前沿科技', lv2: '量子科技' },
{ concept_name: '脑机接口', avg_change_pct: 5.89, stock_count: 14, lv1: '前沿科技', lv2: '脑机接口' },
{ concept_name: 'Neuralink概念', avg_change_pct: 4.12, stock_count: 6, lv1: '前沿科技', lv2: '脑机接口' },
{ concept_name: '神经科技', avg_change_pct: 3.45, stock_count: 8, lv1: '前沿科技', lv2: '脑机接口' },
// 消费电子叶子概念
{ concept_name: 'AI PC', avg_change_pct: 2.34, stock_count: 12, lv1: '消费电子', lv2: '智能终端' },
{ concept_name: 'AI手机', avg_change_pct: 1.89, stock_count: 14, lv1: '消费电子', lv2: '智能终端' },
{ concept_name: '折叠屏', avg_change_pct: 1.56, stock_count: 10, lv1: '消费电子', lv2: '智能终端' },
{ concept_name: 'AR眼镜', avg_change_pct: 4.56, stock_count: 16, lv1: '消费电子', lv2: 'XR与空间计算', lv3: 'XR硬件' },
{ concept_name: 'MR', avg_change_pct: 3.23, stock_count: 12, lv1: '消费电子', lv2: 'XR与空间计算', lv3: 'XR硬件' },
{ concept_name: '智能眼镜', avg_change_pct: 2.89, stock_count: 10, lv1: '消费电子', lv2: 'XR与空间计算', lv3: 'XR硬件' },
{ concept_name: 'VR头显', avg_change_pct: 1.78, stock_count: 8, lv1: '消费电子', lv2: 'XR与空间计算', lv3: 'XR硬件' },
{ concept_name: '华为Mate70', avg_change_pct: 1.23, stock_count: 12, lv1: '消费电子', lv2: '华为产业链' },
{ concept_name: '鸿蒙', avg_change_pct: 0.89, stock_count: 18, lv1: '消费电子', lv2: '华为产业链' },
{ concept_name: '华为昇腾', avg_change_pct: 2.12, stock_count: 10, lv1: '消费电子', lv2: '华为产业链' },
{ concept_name: '麒麟芯片', avg_change_pct: 1.56, stock_count: 8, lv1: '消费电子', lv2: '华为产业链' },
// 智能驾驶叶子概念
{ concept_name: 'Robotaxi', avg_change_pct: 5.67, stock_count: 14, lv1: '智能驾驶与汽车', lv2: '自动驾驶解决方案', lv3: '整体方案' },
{ concept_name: '无人驾驶', avg_change_pct: 4.89, stock_count: 18, lv1: '智能驾驶与汽车', lv2: '自动驾驶解决方案', lv3: '整体方案' },
{ concept_name: '特斯拉FSD', avg_change_pct: 6.12, stock_count: 12, lv1: '智能驾驶与汽车', lv2: '自动驾驶解决方案', lv3: '整体方案' },
{ concept_name: '萝卜快跑', avg_change_pct: 7.23, stock_count: 8, lv1: '智能驾驶与汽车', lv2: '自动驾驶解决方案', lv3: '整体方案' },
{ concept_name: '激光雷达', avg_change_pct: 3.45, stock_count: 16, lv1: '智能驾驶与汽车', lv2: '自动驾驶解决方案', lv3: '核心部件' },
{ concept_name: '毫米波雷达', avg_change_pct: 2.78, stock_count: 10, lv1: '智能驾驶与汽车', lv2: '自动驾驶解决方案', lv3: '核心部件' },
{ concept_name: '域控制器', avg_change_pct: 3.12, stock_count: 12, lv1: '智能驾驶与汽车', lv2: '自动驾驶解决方案', lv3: '核心部件' },
{ concept_name: '比亚迪产业链', avg_change_pct: 2.89, stock_count: 20, lv1: '智能驾驶与汽车', lv2: '智能汽车产业链' },
{ concept_name: '特斯拉产业链', avg_change_pct: 3.56, stock_count: 18, lv1: '智能驾驶与汽车', lv2: '智能汽车产业链' },
{ concept_name: '小米汽车产业链', avg_change_pct: 4.12, stock_count: 15, lv1: '智能驾驶与汽车', lv2: '智能汽车产业链' },
{ concept_name: '新能源汽车', avg_change_pct: 1.78, stock_count: 35, lv1: '智能驾驶与汽车', lv2: '智能汽车产业链' },
// 医药健康叶子概念
{ concept_name: '创新药', avg_change_pct: -1.89, stock_count: 22, lv1: '医药健康', lv2: '创新药' },
{ concept_name: 'CXO', avg_change_pct: -2.34, stock_count: 14, lv1: '医药健康', lv2: '创新药' },
{ concept_name: 'ADC', avg_change_pct: -0.78, stock_count: 10, lv1: '医药健康', lv2: '创新药' },
{ concept_name: '减肥药', avg_change_pct: 1.23, stock_count: 12, lv1: '医药健康', lv2: '创新药' },
{ concept_name: 'GLP-1', avg_change_pct: 0.89, stock_count: 8, lv1: '医药健康', lv2: '创新药' },
{ concept_name: '医疗器械', avg_change_pct: -1.12, stock_count: 18, lv1: '医药健康', lv2: '医疗器械' },
{ concept_name: '手术机器人', avg_change_pct: 0.56, stock_count: 10, lv1: '医药健康', lv2: '医疗器械' },
{ concept_name: '中药', avg_change_pct: -1.45, stock_count: 16, lv1: '医药健康', lv2: '中医药' },
// 大消费叶子概念
{ concept_name: '白酒', avg_change_pct: 1.23, stock_count: 18, lv1: '大消费', lv2: '食品饮料' },
{ concept_name: '啤酒', avg_change_pct: 0.56, stock_count: 10, lv1: '大消费', lv2: '食品饮料' },
{ concept_name: '预制菜', avg_change_pct: -0.34, stock_count: 12, lv1: '大消费', lv2: '食品饮料' },
{ concept_name: '免税', avg_change_pct: 0.89, stock_count: 8, lv1: '大消费', lv2: '消费服务' },
{ concept_name: '旅游', avg_change_pct: 0.45, stock_count: 14, lv1: '大消费', lv2: '消费服务' },
{ concept_name: '电商', avg_change_pct: 0.12, stock_count: 16, lv1: '大消费', lv2: '消费服务' },
{ concept_name: '直播带货', avg_change_pct: -0.23, stock_count: 10, lv1: '大消费', lv2: '消费服务' },
// 金融科技叶子概念
{ concept_name: '数字货币', avg_change_pct: 3.45, stock_count: 16, lv1: '数字经济与金融科技', lv2: '金融科技' },
{ concept_name: '区块链', avg_change_pct: 2.89, stock_count: 18, lv1: '数字经济与金融科技', lv2: '金融科技' },
{ concept_name: 'Web3', avg_change_pct: 2.12, stock_count: 10, lv1: '数字经济与金融科技', lv2: '金融科技' },
{ concept_name: '云计算', avg_change_pct: 2.34, stock_count: 22, lv1: '数字经济与金融科技', lv2: '数字化转型' },
{ concept_name: '大数据', avg_change_pct: 1.78, stock_count: 18, lv1: '数字经济与金融科技', lv2: '数字化转型' },
{ concept_name: '物联网', avg_change_pct: 1.45, stock_count: 16, lv1: '数字经济与金融科技', lv2: '数字化转型' },
{ concept_name: '5G', avg_change_pct: 0.89, stock_count: 20, lv1: '数字经济与金融科技', lv2: '数字化转型' },
{ concept_name: '6G', avg_change_pct: 2.56, stock_count: 10, lv1: '数字经济与金融科技', lv2: '数字化转型' },
{ concept_name: '元宇宙', avg_change_pct: 1.23, stock_count: 14, lv1: '数字经济与金融科技', lv2: '数字化转型' },
// 政策主题叶子概念
{ concept_name: '一带一路', avg_change_pct: 1.89, stock_count: 22, lv1: '政策与主题', lv2: '国家战略' },
{ concept_name: '国产替代', avg_change_pct: 2.34, stock_count: 28, lv1: '政策与主题', lv2: '国家战略' },
{ concept_name: '自主可控', avg_change_pct: 2.12, stock_count: 24, lv1: '政策与主题', lv2: '国家战略' },
{ concept_name: '信创', avg_change_pct: 1.56, stock_count: 18, lv1: '政策与主题', lv2: '国家战略' },
{ concept_name: '数字经济', avg_change_pct: 1.78, stock_count: 20, lv1: '政策与主题', lv2: '国家战略' },
{ concept_name: '粤港澳大湾区', avg_change_pct: 0.89, stock_count: 16, lv1: '政策与主题', lv2: '区域发展' },
{ concept_name: '长三角一体化', avg_change_pct: 0.56, stock_count: 14, lv1: '政策与主题', lv2: '区域发展' },
{ concept_name: '海南自贸港', avg_change_pct: 1.23, stock_count: 10, lv1: '政策与主题', lv2: '区域发展' },
// 周期材料叶子概念
{ concept_name: '黄金', avg_change_pct: -0.45, stock_count: 14, lv1: '周期与材料', lv2: '有色金属' },
{ concept_name: '白银', avg_change_pct: -0.78, stock_count: 10, lv1: '周期与材料', lv2: '有色金属' },
{ concept_name: '铜', avg_change_pct: -1.23, stock_count: 12, lv1: '周期与材料', lv2: '有色金属' },
{ concept_name: '稀土', avg_change_pct: -1.56, stock_count: 16, lv1: '周期与材料', lv2: '有色金属' },
{ concept_name: '锂', avg_change_pct: -2.34, stock_count: 14, lv1: '周期与材料', lv2: '有色金属' },
{ concept_name: '氟化工', avg_change_pct: -0.34, stock_count: 10, lv1: '周期与材料', lv2: '化工材料' },
{ concept_name: '碳纤维', avg_change_pct: 0.12, stock_count: 8, lv1: '周期与材料', lv2: '化工材料' },
{ concept_name: '石墨烯', avg_change_pct: 0.89, stock_count: 12, lv1: '周期与材料', lv2: '化工材料' },
// 国防军工叶子概念
{ concept_name: 'AI军工', avg_change_pct: 3.12, stock_count: 10, lv1: '国防军工', lv2: '无人作战与信息化' },
{ concept_name: '无人机蜂群', avg_change_pct: 2.78, stock_count: 8, lv1: '国防军工', lv2: '无人作战与信息化' },
{ concept_name: '军工信息化', avg_change_pct: 1.89, stock_count: 12, lv1: '国防军工', lv2: '无人作战与信息化' },
{ concept_name: '国产航母', avg_change_pct: 1.56, stock_count: 10, lv1: '国防军工', lv2: '海军装备' },
{ concept_name: '电磁弹射', avg_change_pct: 1.23, stock_count: 8, lv1: '国防军工', lv2: '海军装备' },
{ concept_name: '军贸', avg_change_pct: 1.45, stock_count: 10, lv1: '国防军工', lv2: '军贸出海' },
{ concept_name: '航展概念', avg_change_pct: 0.89, stock_count: 8, lv1: '国防军工', lv2: '军贸出海' }
];
// 计算交易日期(如果没有传入则使用今天)
@@ -814,6 +1454,7 @@ export const conceptHandlers = [
lv1_concepts,
lv2_concepts,
lv3_concepts,
leaf_concepts,
update_time: new Date().toISOString()
});
}),

View File

@@ -239,8 +239,238 @@ const generateDailyAnalysis = (date) => {
};
};
// ==================== 静态文件 Mock Handlers ====================
// 这些 handlers 用于拦截 /data/zt/* 静态文件请求
// 生成 dates.json 数据
const generateDatesJson = () => {
const dates = [];
const today = new Date();
for (let i = 0; i < 60; i++) {
const date = new Date(today);
date.setDate(date.getDate() - i);
const dayOfWeek = date.getDay();
// 跳过周末
if (dayOfWeek !== 0 && dayOfWeek !== 6) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
dates.push({
date: `${year}${month}${day}`,
formatted_date: `${year}-${month}-${day}`,
count: Math.floor(Math.random() * 60) + 40 // 40-100 只涨停股票
});
if (dates.length >= 30) break;
}
}
return { dates };
};
// 生成每日分析 JSON 数据(用于 /data/zt/daily/${date}.json
const generateDailyJson = (date) => {
// 板块名称列表
const sectorNames = [
'公告', '人工智能', 'ChatGPT', '大模型', '算力',
'光伏', '新能源汽车', '锂电池', '储能', '充电桩',
'半导体', '芯片', '集成电路', '国产替代',
'医药', '创新药', 'CXO', '医疗器械',
'军工', '航空航天', '其他'
];
// 股票名称模板
const stockPrefixes = [
'龙头', '科技', '新能', '智能', '数字', '云计', '创新',
'生物', '医疗', '通信', '电子', '材料', '能源', '互联',
'天马', '华鑫', '中科', '东方', '西部', '南方', '北方',
'金龙', '银河', '星辰', '宏达', '盛世', '鹏程', '万里'
];
const stockSuffixes = [
'股份', '科技', '电子', '信息', '新材', '能源', '医药',
'通讯', '智造', '集团', '实业', '控股', '产业', '发展'
];
// 生成所有股票
const stocks = [];
const sectorData = {};
let stockIndex = 0;
sectorNames.forEach((sectorName, sectorIdx) => {
const stockCount = sectorName === '公告'
? Math.floor(Math.random() * 5) + 8 // 公告板块 8-12 只
: sectorName === '其他'
? Math.floor(Math.random() * 4) + 3 // 其他板块 3-6 只
: Math.floor(Math.random() * 8) + 3; // 普通板块 3-10 只
const sectorStockCodes = [];
for (let i = 0; i < stockCount; i++) {
const code = `${Math.random() > 0.6 ? '6' : Math.random() > 0.3 ? '0' : '3'}${String(Math.floor(Math.random() * 100000)).padStart(5, '0')}`;
const continuousDays = Math.floor(Math.random() * 6) + 1;
const ztHour = Math.floor(Math.random() * 4) + 9;
const ztMinute = Math.floor(Math.random() * 60);
const ztSecond = Math.floor(Math.random() * 60);
const prefix = stockPrefixes[Math.floor(Math.random() * stockPrefixes.length)];
const suffix = stockSuffixes[Math.floor(Math.random() * stockSuffixes.length)];
const stockName = `${prefix}${suffix}`;
// 生成关联板块
const coreSectors = [sectorName];
if (Math.random() > 0.5) {
const otherSector = sectorNames[Math.floor(Math.random() * (sectorNames.length - 1))];
if (otherSector !== sectorName && otherSector !== '其他' && otherSector !== '公告') {
coreSectors.push(otherSector);
}
}
stocks.push({
scode: code,
sname: stockName,
zt_time: `${date.slice(0,4)}-${date.slice(4,6)}-${date.slice(6,8)} ${String(ztHour).padStart(2,'0')}:${String(ztMinute).padStart(2,'0')}:${String(ztSecond).padStart(2,'0')}`,
formatted_time: `${String(ztHour).padStart(2,'0')}:${String(ztMinute).padStart(2,'0')}`,
continuous_days: continuousDays === 1 ? '首板' : `${continuousDays}连板`,
brief: sectorName === '公告'
? `${stockName}发布重大公告,公司拟收购资产/重组/增发等利好消息。`
: `${sectorName}板块异动,${stockName}因板块热点涨停。公司是${sectorName}行业核心标的。`,
summary: `${sectorName}概念活跃`,
first_time: `${date.slice(0,4)}-${date.slice(4,6)}-${String(parseInt(date.slice(6,8)) - (continuousDays - 1)).padStart(2,'0')}`,
change_pct: parseFloat((Math.random() * 1.5 + 9.5).toFixed(2)),
core_sectors: coreSectors
});
sectorStockCodes.push(code);
stockIndex++;
}
sectorData[sectorName] = {
count: stockCount,
stock_codes: sectorStockCodes
};
});
// 生成词频数据
const wordFreqData = [
{ name: '人工智能', value: Math.floor(Math.random() * 30) + 20 },
{ name: 'ChatGPT', value: Math.floor(Math.random() * 25) + 15 },
{ name: '大模型', value: Math.floor(Math.random() * 20) + 12 },
{ name: '算力', value: Math.floor(Math.random() * 18) + 10 },
{ name: '光伏', value: Math.floor(Math.random() * 15) + 10 },
{ name: '新能源', value: Math.floor(Math.random() * 15) + 8 },
{ name: '锂电池', value: Math.floor(Math.random() * 12) + 8 },
{ name: '储能', value: Math.floor(Math.random() * 12) + 6 },
{ name: '半导体', value: Math.floor(Math.random() * 15) + 10 },
{ name: '芯片', value: Math.floor(Math.random() * 15) + 8 },
{ name: '集成电路', value: Math.floor(Math.random() * 10) + 5 },
{ name: '国产替代', value: Math.floor(Math.random() * 10) + 5 },
{ name: '医药', value: Math.floor(Math.random() * 12) + 6 },
{ name: '创新药', value: Math.floor(Math.random() * 10) + 5 },
{ name: '医疗器械', value: Math.floor(Math.random() * 8) + 4 },
{ name: '军工', value: Math.floor(Math.random() * 10) + 5 },
{ name: '航空航天', value: Math.floor(Math.random() * 8) + 4 },
{ name: '数字经济', value: Math.floor(Math.random() * 12) + 6 },
{ name: '工业4.0', value: Math.floor(Math.random() * 8) + 4 },
{ name: '机器人', value: Math.floor(Math.random() * 10) + 5 },
{ name: '自动驾驶', value: Math.floor(Math.random() * 8) + 4 },
{ name: '元宇宙', value: Math.floor(Math.random() * 6) + 3 },
{ name: 'Web3.0', value: Math.floor(Math.random() * 5) + 2 },
{ name: '区块链', value: Math.floor(Math.random() * 5) + 2 },
];
return {
date: date,
total_stocks: stocks.length,
total_sectors: Object.keys(sectorData).length,
stocks: stocks,
sector_data: sectorData,
word_freq_data: wordFreqData,
summary: {
top_sector: '人工智能',
top_sector_count: sectorData['人工智能']?.count || 0,
announcement_stocks: sectorData['公告']?.count || 0,
zt_time_distribution: {
morning: Math.floor(stocks.length * 0.4),
afternoon: Math.floor(stocks.length * 0.6),
}
}
};
};
// 生成 stocks.jsonl 数据
const generateStocksJsonl = () => {
const stocks = [];
const today = new Date();
// 生成 200 只历史涨停股票记录
for (let i = 0; i < 200; i++) {
const daysAgo = Math.floor(Math.random() * 30);
const date = new Date(today);
date.setDate(date.getDate() - daysAgo);
// 跳过周末
while (date.getDay() === 0 || date.getDay() === 6) {
date.setDate(date.getDate() - 1);
}
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
stocks.push({
scode: `${Math.random() > 0.6 ? '6' : Math.random() > 0.3 ? '0' : '3'}${String(Math.floor(Math.random() * 100000)).padStart(5, '0')}`,
sname: ['龙头', '科技', '新能', '智能', '数字', '云计'][Math.floor(Math.random() * 6)] +
['股份', '科技', '电子', '信息', '新材'][Math.floor(Math.random() * 5)],
date: `${year}${month}${day}`,
formatted_date: `${year}-${month}-${day}`,
continuous_days: Math.floor(Math.random() * 5) + 1,
core_sectors: [['人工智能', 'ChatGPT', '光伏', '锂电池', '芯片'][Math.floor(Math.random() * 5)]]
});
}
return stocks;
};
// Mock Handlers
export const limitAnalyseHandlers = [
// ==================== 静态文件路径 Handlers ====================
// 1. /data/zt/dates.json - 可用日期列表
http.get('/data/zt/dates.json', async () => {
await delay(200);
console.log('[Mock LimitAnalyse] 获取 dates.json');
const data = generateDatesJson();
return HttpResponse.json(data);
}),
// 2. /data/zt/daily/:date.json - 每日分析数据
http.get('/data/zt/daily/:date', async ({ params }) => {
await delay(300);
// 移除 .json 后缀和查询参数
const dateParam = params.date.replace('.json', '').split('?')[0];
console.log('[Mock LimitAnalyse] 获取每日数据:', dateParam);
const data = generateDailyJson(dateParam);
return HttpResponse.json(data);
}),
// 3. /data/zt/stocks.jsonl - 股票列表(用于搜索)
http.get('/data/zt/stocks.jsonl', async () => {
await delay(200);
console.log('[Mock LimitAnalyse] 获取 stocks.jsonl');
const stocks = generateStocksJsonl();
// JSONL 格式:每行一个 JSON
const jsonl = stocks.map(s => JSON.stringify(s)).join('\n');
return new HttpResponse(jsonl, {
headers: { 'Content-Type': 'text/plain' }
});
}),
// ==================== API 路径 Handlers (兼容旧版本) ====================
// 1. 获取可用日期列表
http.get('http://111.198.58.126:5001/api/v1/dates/available', async () => {
await delay(300);

View File

@@ -825,7 +825,7 @@ const ConceptTimelineModal = ({
bg="whiteAlpha.100"
borderRadius="lg"
border="1px solid"
borderColor="orange.400"
borderColor="red.500"
flexShrink={0}
>
<Text fontSize={{ base: 'xs', md: 'sm' }} fontWeight="bold">🔥</Text>

View File

@@ -1006,7 +1006,7 @@ const ForceGraphView = ({
// 获取容器高度
const containerHeight = useMemo(() => {
if (isFullscreen) return '100vh';
if (isFullscreen) return 'calc(100vh - 60px)';
return isMobile ? '500px' : '700px';
}, [isFullscreen, isMobile]);
@@ -1069,161 +1069,84 @@ const ForceGraphView = ({
}
return (
<Box
ref={containerRef}
position={isFullscreen ? 'fixed' : 'relative'}
top={isFullscreen ? 0 : 'auto'}
left={isFullscreen ? 0 : 'auto'}
right={isFullscreen ? 0 : 'auto'}
bottom={isFullscreen ? 0 : 'auto'}
zIndex={isFullscreen ? 1000 : 'auto'}
borderRadius={isFullscreen ? '0' : '3xl'}
overflow="hidden"
border={isFullscreen ? 'none' : '1px solid'}
borderColor="whiteAlpha.100"
h={containerHeight}
bg="transparent"
>
{/* 极光背景层 */}
<Box
position="absolute"
top={0}
left={0}
right={0}
bottom={0}
bg="linear-gradient(135deg, #0F172A 0%, #1E1B4B 25%, #312E81 50%, #1E1B4B 75%, #0F172A 100%)"
backgroundSize="400% 400%"
animation={`${auroraAnimation} 15s ease infinite`}
/>
<VStack spacing={3} align="stretch" w="100%">
{/* 外部工具栏 - 在蓝紫色背景外面 */}
<HStack spacing={3} px={2} justify="space-between" align="center">
<HStack spacing={3}>
{/* 返回按钮 */}
{drillPath && (
<Tooltip label="返回上一层" placement="bottom">
<IconButton
size="sm"
icon={<FaArrowLeft />}
onClick={handleGoBack}
bg="whiteAlpha.100"
color="white"
border="1px solid"
borderColor="whiteAlpha.200"
borderRadius="full"
_hover={{
bg: 'purple.500',
borderColor: 'purple.400',
transform: 'scale(1.05)',
}}
transition="all 0.2s"
aria-label="返回"
/>
</Tooltip>
)}
{/* 弥散光晕层 */}
<Box
position="absolute"
top="20%"
left="10%"
w="300px"
h="300px"
bg="radial-gradient(circle, rgba(139, 92, 246, 0.3) 0%, transparent 70%)"
filter="blur(60px)"
pointerEvents="none"
animation={`${glowPulse} 4s ease-in-out infinite`}
/>
<Box
position="absolute"
bottom="20%"
right="15%"
w="250px"
h="250px"
bg="radial-gradient(circle, rgba(59, 130, 246, 0.25) 0%, transparent 70%)"
filter="blur(50px)"
pointerEvents="none"
animation={`${glowPulse} 5s ease-in-out infinite 1s`}
/>
<Box
position="absolute"
top="50%"
right="30%"
w="200px"
h="200px"
bg="radial-gradient(circle, rgba(236, 72, 153, 0.2) 0%, transparent 70%)"
filter="blur(40px)"
pointerEvents="none"
animation={`${glowPulse} 6s ease-in-out infinite 2s`}
/>
{/* 顶部工具栏 - 毛玻璃风格 */}
<Flex
position="absolute"
top={isFullscreen ? '70px' : 4}
left={4}
right={4}
justify="space-between"
align="flex-start"
zIndex={10}
pointerEvents="none"
>
{/* 左侧标题和面包屑 */}
<VStack align="start" spacing={2} pointerEvents="auto">
<HStack spacing={3}>
{/* 返回按钮 */}
{drillPath && (
<Tooltip label="返回上一层" placement="bottom">
<IconButton
size="sm"
icon={<FaArrowLeft />}
onClick={handleGoBack}
bg="rgba(255, 255, 255, 0.1)"
backdropFilter="blur(20px)"
color="white"
border="1px solid"
borderColor="whiteAlpha.200"
borderRadius="full"
_hover={{
bg: 'rgba(139, 92, 246, 0.4)',
borderColor: 'purple.400',
transform: 'scale(1.05)',
}}
transition="all 0.2s"
aria-label="返回"
/>
</Tooltip>
)}
<HStack
bg="rgba(255, 255, 255, 0.08)"
backdropFilter="blur(20px)"
px={5}
py={2.5}
borderRadius="full"
border="1px solid"
borderColor="whiteAlpha.150"
boxShadow="0 8px 32px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.1)"
>
<Icon as={FaTh} color="purple.300" />
<Text color="white" fontWeight="bold" fontSize="sm">
概念矩形树图
</Text>
</HStack>
{/* 面包屑导航 */}
<HStack
bg="rgba(255, 255, 255, 0.06)"
backdropFilter="blur(20px)"
px={4}
py={2}
borderRadius="full"
border="1px solid"
borderColor="whiteAlpha.100"
spacing={2}
>
{breadcrumbItems.map((item, index) => (
<HStack key={index} spacing={2}>
{index > 0 && (
<Icon as={FaChevronRight} color="whiteAlpha.400" boxSize={3} />
)}
<Text
color={index === breadcrumbItems.length - 1 ? 'purple.300' : 'whiteAlpha.700'}
fontSize="sm"
fontWeight={index === breadcrumbItems.length - 1 ? 'bold' : 'normal'}
cursor={index < breadcrumbItems.length - 1 ? 'pointer' : 'default'}
_hover={index < breadcrumbItems.length - 1 ? { color: 'white' } : {}}
transition="color 0.2s"
onClick={() => {
if (index < breadcrumbItems.length - 1) {
setDrillPath(item.path);
}
}}
>
{item.label}
</Text>
</HStack>
))}
</HStack>
<HStack
bg="whiteAlpha.100"
px={4}
py={2}
borderRadius="full"
border="1px solid"
borderColor="whiteAlpha.200"
>
<Icon as={FaTh} color="purple.300" />
<Text color="white" fontWeight="bold" fontSize="sm">
概念矩形树图
</Text>
</HStack>
</VStack>
{/* 面包屑导航 */}
<HStack
bg="whiteAlpha.50"
px={4}
py={2}
borderRadius="full"
border="1px solid"
borderColor="whiteAlpha.100"
spacing={2}
>
{breadcrumbItems.map((item, index) => (
<HStack key={index} spacing={2}>
{index > 0 && (
<Icon as={FaChevronRight} color="whiteAlpha.400" boxSize={3} />
)}
<Text
color={index === breadcrumbItems.length - 1 ? 'purple.300' : 'whiteAlpha.700'}
fontSize="sm"
fontWeight={index === breadcrumbItems.length - 1 ? 'bold' : 'normal'}
cursor={index < breadcrumbItems.length - 1 ? 'pointer' : 'default'}
_hover={index < breadcrumbItems.length - 1 ? { color: 'white' } : {}}
transition="color 0.2s"
onClick={() => {
if (index < breadcrumbItems.length - 1) {
setDrillPath(item.path);
}
}}
>
{item.label}
</Text>
</HStack>
))}
</HStack>
</HStack>
{/* 右侧控制按钮 */}
<HStack spacing={2} pointerEvents="auto">
<HStack spacing={2}>
{priceLoading && <Spinner size="sm" color="purple.300" />}
{drillPath && (
@@ -1232,14 +1155,13 @@ const ForceGraphView = ({
size="sm"
icon={<FaHome />}
onClick={handleGoHome}
bg="rgba(255, 255, 255, 0.1)"
backdropFilter="blur(20px)"
bg="whiteAlpha.100"
color="white"
border="1px solid"
borderColor="whiteAlpha.200"
borderRadius="full"
_hover={{
bg: 'rgba(139, 92, 246, 0.4)',
bg: 'purple.500',
borderColor: 'purple.400',
transform: 'scale(1.05)',
}}
@@ -1255,14 +1177,13 @@ const ForceGraphView = ({
icon={<FaSync />}
onClick={handleRefresh}
isLoading={priceLoading}
bg="rgba(255, 255, 255, 0.1)"
backdropFilter="blur(20px)"
bg="whiteAlpha.100"
color="white"
border="1px solid"
borderColor="whiteAlpha.200"
borderRadius="full"
_hover={{
bg: 'rgba(255, 255, 255, 0.2)',
bg: 'whiteAlpha.200',
borderColor: 'whiteAlpha.300',
transform: 'scale(1.05)',
}}
@@ -1276,14 +1197,13 @@ const ForceGraphView = ({
size="sm"
icon={isFullscreen ? <FaCompress /> : <FaExpand />}
onClick={toggleFullscreen}
bg="rgba(255, 255, 255, 0.1)"
backdropFilter="blur(20px)"
bg="whiteAlpha.100"
color="white"
border="1px solid"
borderColor="whiteAlpha.200"
borderRadius="full"
_hover={{
bg: 'rgba(255, 255, 255, 0.2)',
bg: 'whiteAlpha.200',
borderColor: 'whiteAlpha.300',
transform: 'scale(1.05)',
}}
@@ -1292,9 +1212,72 @@ const ForceGraphView = ({
/>
</Tooltip>
</HStack>
</Flex>
</HStack>
{/* 底部图例 - 毛玻璃风格 */}
{/* 蓝紫色背景容器 */}
<Box
ref={containerRef}
position={isFullscreen ? 'fixed' : 'relative'}
top={isFullscreen ? '60px' : 'auto'}
left={isFullscreen ? 0 : 'auto'}
right={isFullscreen ? 0 : 'auto'}
bottom={isFullscreen ? 0 : 'auto'}
zIndex={isFullscreen ? 1000 : 'auto'}
borderRadius={isFullscreen ? '0' : '3xl'}
overflow="hidden"
border={isFullscreen ? 'none' : '1px solid'}
borderColor="whiteAlpha.100"
h={containerHeight}
bg="transparent"
>
{/* 极光背景层 */}
<Box
position="absolute"
top={0}
left={0}
right={0}
bottom={0}
bg="linear-gradient(135deg, #0F172A 0%, #1E1B4B 25%, #312E81 50%, #1E1B4B 75%, #0F172A 100%)"
backgroundSize="400% 400%"
animation={`${auroraAnimation} 15s ease infinite`}
/>
{/* 弥散光晕层 */}
<Box
position="absolute"
top="20%"
left="10%"
w="300px"
h="300px"
bg="radial-gradient(circle, rgba(139, 92, 246, 0.3) 0%, transparent 70%)"
filter="blur(60px)"
pointerEvents="none"
animation={`${glowPulse} 4s ease-in-out infinite`}
/>
<Box
position="absolute"
bottom="20%"
right="15%"
w="250px"
h="250px"
bg="radial-gradient(circle, rgba(59, 130, 246, 0.25) 0%, transparent 70%)"
filter="blur(50px)"
pointerEvents="none"
animation={`${glowPulse} 5s ease-in-out infinite 1s`}
/>
<Box
position="absolute"
top="50%"
right="30%"
w="200px"
h="200px"
bg="radial-gradient(circle, rgba(236, 72, 153, 0.2) 0%, transparent 70%)"
filter="blur(40px)"
pointerEvents="none"
animation={`${glowPulse} 6s ease-in-out infinite 2s`}
/>
{/* 底部图例 - 毛玻璃风格 */}
<Flex
position="absolute"
bottom={4}
@@ -1370,7 +1353,8 @@ const ForceGraphView = ({
onEvents={onChartEvents}
opts={{ renderer: 'canvas' }}
/>
</Box>
</Box>
</VStack>
);
};

View File

@@ -814,49 +814,10 @@ const HierarchyView = ({
{/* 内容层 */}
<Box position="relative" zIndex={1}>
{/* 简化的工具栏 - 仅显示功能按钮 */}
<Flex
justify="flex-end"
align="center"
mb={4}
gap={2}
>
{priceLoading && (
<Spinner size="sm" color="purple.300" mr={2} />
)}
<Tooltip label="刷新涨跌幅" placement="top">
<IconButton
size="sm"
icon={<FaSync />}
onClick={handleRefreshPrice}
isLoading={priceLoading}
bg="whiteAlpha.100"
color="white"
border="1px solid"
borderColor="whiteAlpha.200"
_hover={{ bg: 'whiteAlpha.200' }}
aria-label="刷新涨跌幅"
/>
</Tooltip>
<Tooltip label={isFullscreen ? '退出全屏' : '全屏'} placement="top">
<IconButton
size="sm"
icon={isFullscreen ? <FaCompress /> : <FaExpand />}
onClick={toggleFullscreen}
bg="whiteAlpha.100"
color="white"
border="1px solid"
borderColor="whiteAlpha.200"
_hover={{ bg: 'whiteAlpha.200' }}
aria-label={isFullscreen ? '退出全屏' : '全屏'}
/>
</Tooltip>
</Flex>
{/* 面包屑导航 */}
{/* 面包屑导航 + 工具栏(同一行) */}
<Flex
align="center"
justify="space-between"
mb={5}
p={3}
bg="whiteAlpha.50"
@@ -864,31 +825,68 @@ const HierarchyView = ({
borderRadius="2xl"
border="1px solid"
borderColor="whiteAlpha.100"
flexWrap="wrap"
gap={1}
gap={2}
>
{breadcrumbs.map((crumb, index) => (
<React.Fragment key={index}>
{index > 0 && (
<Icon as={FaChevronRight} color="whiteAlpha.400" boxSize={3} mx={1} />
)}
<Button
{/* 左侧:面包屑导航 */}
<Flex align="center" flexWrap="wrap" gap={1} flex={1}>
{breadcrumbs.map((crumb, index) => (
<React.Fragment key={index}>
{index > 0 && (
<Icon as={FaChevronRight} color="whiteAlpha.400" boxSize={3} mx={1} />
)}
<Button
size="sm"
variant="ghost"
bg={index === breadcrumbs.length - 1 ? 'purple.500' : 'transparent'}
color={index === breadcrumbs.length - 1 ? 'white' : 'whiteAlpha.700'}
leftIcon={index === 0 ? <FaHome /> : undefined}
onClick={() => handleBreadcrumbClick(crumb, index)}
isDisabled={index === breadcrumbs.length - 1}
fontWeight={index === breadcrumbs.length - 1 ? 'bold' : 'medium'}
borderRadius="xl"
_hover={index !== breadcrumbs.length - 1 ? { bg: 'whiteAlpha.100' } : {}}
boxShadow={index === breadcrumbs.length - 1 ? '0 0 20px rgba(139, 92, 246, 0.5)' : 'none'}
>
{crumb.label}
</Button>
</React.Fragment>
))}
</Flex>
{/* 右侧:工具栏按钮 */}
<HStack spacing={2} flexShrink={0}>
{priceLoading && (
<Spinner size="sm" color="purple.300" />
)}
<Tooltip label="刷新涨跌幅" placement="top">
<IconButton
size="sm"
variant="ghost"
bg={index === breadcrumbs.length - 1 ? 'purple.500' : 'transparent'}
color={index === breadcrumbs.length - 1 ? 'white' : 'whiteAlpha.700'}
leftIcon={index === 0 ? <FaHome /> : undefined}
onClick={() => handleBreadcrumbClick(crumb, index)}
isDisabled={index === breadcrumbs.length - 1}
fontWeight={index === breadcrumbs.length - 1 ? 'bold' : 'medium'}
borderRadius="xl"
_hover={index !== breadcrumbs.length - 1 ? { bg: 'whiteAlpha.100' } : {}}
boxShadow={index === breadcrumbs.length - 1 ? '0 0 20px rgba(139, 92, 246, 0.5)' : 'none'}
>
{crumb.label}
</Button>
</React.Fragment>
))}
icon={<FaSync />}
onClick={handleRefreshPrice}
isLoading={priceLoading}
bg="whiteAlpha.100"
color="white"
border="1px solid"
borderColor="whiteAlpha.200"
_hover={{ bg: 'whiteAlpha.200' }}
aria-label="刷新涨跌幅"
/>
</Tooltip>
<Tooltip label={isFullscreen ? '退出全屏' : '全屏'} placement="top">
<IconButton
size="sm"
icon={isFullscreen ? <FaCompress /> : <FaExpand />}
onClick={toggleFullscreen}
bg="whiteAlpha.100"
color="white"
border="1px solid"
borderColor="whiteAlpha.200"
_hover={{ bg: 'whiteAlpha.200' }}
aria-label={isFullscreen ? '退出全屏' : '全屏'}
/>
</Tooltip>
</HStack>
</Flex>
{/* 图例说明 */}

View File

@@ -1417,7 +1417,7 @@ const ConceptCenter = () => {
align={{ base: 'stretch', lg: 'center' }}
gap={4}
>
{/* 使用通用日期选择器组件 */}
{/* 使用通用日期选择器组件 - 不显示最新日期提示,由下方单独渲染 */}
<TradeDatePicker
value={selectedDate}
onChange={(date) => {
@@ -1432,9 +1432,10 @@ const ConceptCenter = () => {
latestTradeDate={latestTradeDate}
label="交易日期"
isDarkMode={true}
showLatestTradeDateTip={false}
/>
{/* 快捷按钮 - 深色主题,更有区分度 */}
{/* 快捷按钮 - 紧跟日期选择器 */}
<ButtonGroup size="sm" flexWrap="wrap" spacing={2}>
<Button
onClick={() => handleQuickDateSelect(0)}
@@ -1505,6 +1506,26 @@ const ConceptCenter = () => {
一月前
</Button>
</ButtonGroup>
{/* 最新交易日期提示 - 靠右显示 */}
{latestTradeDate && (
<Tooltip label="数据库中最新的交易日期">
<HStack
spacing={1.5}
ml="auto"
px={2}
py={1}
opacity={0.7}
_hover={{ opacity: 1 }}
transition="opacity 0.2s"
>
<Icon as={InfoIcon} color="blue.300" boxSize={3} />
<Text fontSize="xs" color="blue.200">
数据更新至 {latestTradeDate.toLocaleDateString('zh-CN')}
</Text>
</HStack>
</Tooltip>
)}
</Flex>
</Box>
);
@@ -1752,52 +1773,55 @@ const ConceptCenter = () => {
align={{ base: 'stretch', md: 'center' }}
gap={4}
>
<HStack spacing={4} align="center">
<Icon as={FaTags} boxSize={4} color="purple.300" />
<Text fontWeight="bold" color="white">排序方式</Text>
<Select
value={sortBy}
onChange={(e) => handleSortChange(e.target.value)}
width="200px"
focusBorderColor="purple.400"
borderColor="whiteAlpha.300"
borderRadius="lg"
fontWeight="medium"
color="white"
bg="whiteAlpha.50"
_hover={{ borderColor: 'purple.400' }}
sx={{
option: {
bg: 'gray.800',
color: 'white',
},
}}
>
<option value="change_pct">涨跌幅</option>
<option value="_score">相关度</option>
<option value="stock_count">股票数量</option>
<option value="outbreak_date">爆发日期</option>
</Select>
{searchQuery && sortBy === '_score' && (
<Tooltip label="搜索时自动切换到相关度排序,以显示最匹配的结果。您也可以手动切换其他排序方式。">
<HStack
spacing={1}
bg="blue.500"
px={3}
py={1}
borderRadius="full"
boxShadow="0 0 10px rgba(59, 130, 246, 0.4)"
>
<Icon as={InfoIcon} color="white" boxSize={3} />
<Text fontSize="xs" color="white" fontWeight="medium">
智能排序
</Text>
</HStack>
</Tooltip>
)}
</HStack>
{/* 排序方式 - 仅在列表视图显示 */}
{viewMode === 'list' && (
<HStack spacing={4} align="center">
<Icon as={FaTags} boxSize={4} color="purple.300" />
<Text fontWeight="bold" color="white">排序方式</Text>
<Select
value={sortBy}
onChange={(e) => handleSortChange(e.target.value)}
width="200px"
focusBorderColor="purple.400"
borderColor="whiteAlpha.300"
borderRadius="lg"
fontWeight="medium"
color="white"
bg="whiteAlpha.50"
_hover={{ borderColor: 'purple.400' }}
sx={{
option: {
bg: 'gray.800',
color: 'white',
},
}}
>
<option value="change_pct">涨跌幅</option>
<option value="_score">相关度</option>
<option value="stock_count">股票数量</option>
<option value="outbreak_date">爆发日期</option>
</Select>
{searchQuery && sortBy === '_score' && (
<Tooltip label="搜索时自动切换到相关度排序,以显示最匹配的结果。您也可以手动切换其他排序方式。">
<HStack
spacing={1}
bg="blue.500"
px={3}
py={1}
borderRadius="full"
boxShadow="0 0 10px rgba(59, 130, 246, 0.4)"
>
<Icon as={InfoIcon} color="white" boxSize={3} />
<Text fontSize="xs" color="white" fontWeight="medium">
智能排序
</Text>
</HStack>
</Tooltip>
)}
</HStack>
)}
<ButtonGroup size="sm" isAttached variant="outline">
<ButtonGroup size="sm" isAttached variant="outline" ml={viewMode !== 'list' ? 'auto' : undefined}>
<Tooltip label="概念矩形树图" placement="top">
<IconButton
icon={<FaCube />}

View File

@@ -297,15 +297,17 @@ const SectorHeatMap = ({ data }) => {
rx="8"
style={{
cursor: 'pointer',
transition: 'all 0.3s'
transition: 'all 0.2s ease-in-out'
}}
onMouseEnter={(e) => {
e.target.style.opacity = '0.8';
e.target.style.transform = 'scale(1.05)';
e.target.style.stroke = '#FFD700';
e.target.style.strokeWidth = '4';
e.target.style.filter = 'brightness(1.2) drop-shadow(0 0 8px rgba(255, 215, 0, 0.6))';
}}
onMouseLeave={(e) => {
e.target.style.opacity = '1';
e.target.style.transform = 'scale(1)';
e.target.style.stroke = '#fff';
e.target.style.strokeWidth = '2';
e.target.style.filter = 'none';
}}
>
<title>{`${sector.name}: ${sector.count}只涨停`}</title>