// src/mocks/handlers/concept.js // 概念相关的 Mock Handlers import { http, HttpResponse } from 'msw'; // 模拟延迟 const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms)); // 生成历史触发时间(3-5个历史日期) const generateHappenedTimes = (seed) => { const times = []; const count = 3 + (seed % 3); // 3-5个时间点 for (let i = 0; i < count; i++) { const daysAgo = 30 + (seed * 7 + i * 11) % 330; // 30-360天前 const date = new Date(); date.setDate(date.getDate() - daysAgo); times.push(date.toISOString().split('T')[0]); } return times.sort().reverse(); // 降序排列 }; // 生成核心相关股票 const generateStocksForConcept = (seed, count = 4) => { const stockPool = [ { name: '贵州茅台', code: '600519' }, { name: '宁德时代', code: '300750' }, { name: '中国平安', code: '601318' }, { name: '比亚迪', code: '002594' }, { name: '隆基绿能', code: '601012' }, { name: '阳光电源', code: '300274' }, { name: '三一重工', code: '600031' }, { name: '中芯国际', code: '688981' }, { name: '京东方A', code: '000725' }, { name: '立讯精密', code: '002475' } ]; const stocks = []; for (let i = 0; i < count; i++) { const stockIndex = (seed + i * 7) % stockPool.length; const stock = stockPool[stockIndex]; stocks.push({ stock_name: stock.name, stock_code: stock.code, reason: `作为行业龙头企业,${stock.name}在该领域具有核心竞争优势,市场份额领先,技术实力雄厚。`, change_pct: parseFloat((Math.random() * 15 - 5).toFixed(2)) // -5% ~ +10% }); } return stocks; }; // 生成热门概念数据 export const generatePopularConcepts = (size = 20) => { const concepts = [ '人工智能', '新能源汽车', '半导体', '光伏', '锂电池', '储能', '氢能源', '风电', '特高压', '工业母机', '军工', '航空航天', '卫星导航', '量子科技', '数字货币', '云计算', '大数据', '物联网', '5G', '6G', '元宇宙', '虚拟现实', 'AIGC', 'ChatGPT', '算力', '芯片设计', '芯片制造', '半导体设备', '半导体材料', 'EDA', '新能源', '风光储', '充电桩', '智能电网', '特斯拉', '比亚迪', '宁德时代', '华为', '苹果产业链', '鸿蒙', '国产软件', '信创', '网络安全', '数据安全', '量子通信', '医疗器械', '创新药', '医美', 'CXO', '生物医药', '疫苗', '中药', '医疗信息化', '智慧医疗', '基因测序' ]; const conceptDescriptions = { '人工智能': '人工智能是"技术突破+政策扶持"双轮驱动的硬科技主题。随着大模型技术的突破,AI应用场景不断拓展,预计将催化算力、数据、应用三大产业链。', '新能源汽车': '新能源汽车行业景气度持续向好,渗透率不断提升。政策支持力度大,产业链上下游企业均受益明显。', '半导体': '国产半导体替代加速,自主可控需求强烈。政策和资金支持力度大,行业迎来黄金发展期。', '光伏': '光伏装机量快速增长,成本持续下降,行业景气度维持高位。双碳目标下,光伏行业前景广阔。', '锂电池': '锂电池技术进步,成本优势扩大,下游应用领域持续扩张。新能源汽车和储能需求旺盛。', '储能': '储能市场爆发式增长,政策支持力度大,应用场景不断拓展。未来市场空间巨大。', '默认': '该概念市场关注度较高,具有一定的投资价值。相关企业技术实力雄厚,市场前景广阔。' }; const matchTypes = ['hybrid_knn', 'keyword', 'semantic']; const results = []; for (let i = 0; i < Math.min(size, concepts.length); i++) { const changePct = (Math.random() * 12 - 2).toFixed(2); // -2% 到 +10% const stockCount = Math.floor(Math.random() * 50) + 10; // 10-60 只股票 const score = parseFloat((Math.random() * 5 + 3).toFixed(2)); // 3-8 分数范围 results.push({ concept: concepts[i], concept_id: `CONCEPT_${1000 + i}`, stock_count: stockCount, score: score, // 相关度分数 match_type: matchTypes[i % 3], // 匹配类型 description: conceptDescriptions[concepts[i]] || conceptDescriptions['默认'], price_info: { avg_change_pct: parseFloat(changePct), avg_price: parseFloat((Math.random() * 100 + 10).toFixed(2)), total_market_cap: parseFloat((Math.random() * 1000 + 100).toFixed(2)) }, happened_times: generateHappenedTimes(i), // 历史触发时间 stocks: generateStocksForConcept(i, 4), // 核心相关股票 hot_score: Math.floor(Math.random() * 100) }); } // 按涨跌幅降序排序 results.sort((a, b) => b.price_info.avg_change_pct - a.price_info.avg_change_pct); return results; }; // 生成完整的概念统计数据(用于 ConceptStatsPanel) const generateConceptStats = () => { // 热门概念(涨幅最大的前5) const hot_concepts = [ { name: '小米大模型', change_pct: 18.76, stock_count: 12, news_count: 35 }, { name: '人工智能', change_pct: 15.67, stock_count: 45, news_count: 23 }, { name: '新能源汽车', change_pct: 12.34, stock_count: 38, news_count: 18 }, { name: '芯片概念', change_pct: 9.87, stock_count: 52, news_count: 31 }, { name: '5G通信', change_pct: 8.45, stock_count: 29, news_count: 15 }, ]; // 冷门概念(跌幅最大的前5) const cold_concepts = [ { name: '房地产', change_pct: -8.76, stock_count: 33, news_count: 12 }, { name: '煤炭开采', change_pct: -6.54, stock_count: 25, news_count: 8 }, { name: '传统零售', change_pct: -5.43, stock_count: 19, news_count: 6 }, { name: '钢铁冶炼', change_pct: -4.21, stock_count: 28, news_count: 9 }, { name: '纺织服装', change_pct: -3.98, stock_count: 15, news_count: 4 }, ]; // 活跃概念(新闻+研报最多的前5) const active_concepts = [ { name: '人工智能', news_count: 89, report_count: 15, total_mentions: 104 }, { name: '芯片概念', news_count: 76, report_count: 12, total_mentions: 88 }, { name: '新能源汽车', news_count: 65, report_count: 18, total_mentions: 83 }, { name: '生物医药', news_count: 54, report_count: 9, total_mentions: 63 }, { name: '量子科技', news_count: 41, report_count: 7, total_mentions: 48 }, ]; // 波动最大的概念(前5) const volatile_concepts = [ { name: '区块链', volatility: 23.45, avg_change: 3.21, max_change: 12.34 }, { name: '元宇宙', volatility: 21.87, avg_change: 2.98, max_change: 11.76 }, { name: '虚拟现实', volatility: 19.65, avg_change: -1.23, max_change: 9.87 }, { name: '游戏概念', volatility: 18.32, avg_change: 4.56, max_change: 10.45 }, { name: '在线教育', volatility: 17.89, avg_change: -2.11, max_change: 8.76 }, ]; // 动量概念(连续上涨的前5) const momentum_concepts = [ { name: '数字经济', consecutive_days: 5, total_change: 18.76, avg_daily: 3.75 }, { name: '云计算', consecutive_days: 4, total_change: 14.32, avg_daily: 3.58 }, { name: '物联网', consecutive_days: 4, total_change: 12.89, avg_daily: 3.22 }, { name: '大数据', consecutive_days: 3, total_change: 11.45, avg_daily: 3.82 }, { name: '工业互联网', consecutive_days: 3, total_change: 9.87, avg_daily: 3.29 }, ]; return { hot_concepts, cold_concepts, active_concepts, volatile_concepts, momentum_concepts }; }; // 概念相关的 Handlers export const conceptHandlers = [ // 搜索概念(热门概念) 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] 搜索概念:', { query, size, page, sort_by }); // 生成数据(不过滤,模拟真实 API 的语义搜索返回热门概念) let results = generatePopularConcepts(size); console.log('[Mock Concept] 生成概念数量:', results.length); // Mock 环境下不做过滤,直接返回热门概念 // 真实环境会根据 query 进行语义搜索 // 根据排序字段排序 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] 搜索概念失败:', error); return HttpResponse.json( { results: [], total: 0, error: '搜索失败' }, { status: 500 } ); } }), // 获取单个概念详情 http.get('/concept-api/concepts/:conceptId', async ({ params }) => { await delay(300); const { conceptId } = params; console.log('[Mock Concept] 获取概念详情:', conceptId); const concepts = generatePopularConcepts(50); const concept = concepts.find(c => c.concept_id === conceptId || c.concept === conceptId); if (concept) { return HttpResponse.json({ ...concept, related_stocks: [ { stock_code: '600519', stock_name: '贵州茅台', change_pct: 2.34 }, { stock_code: '000858', stock_name: '五粮液', change_pct: 1.89 }, { stock_code: '000568', stock_name: '泸州老窖', change_pct: 3.12 } ], news: [ { title: `${concept.concept}板块异动`, date: '2024-10-24', source: '财经新闻' } ] }); } else { return HttpResponse.json( { error: '概念不存在' }, { status: 404 } ); } }), // 获取概念相关股票(concept-api 路由) http.get('/concept-api/concepts/:conceptId/stocks', async ({ params, request }) => { await delay(300); const { conceptId } = params; const url = new URL(request.url); const limit = parseInt(url.searchParams.get('limit') || '20'); console.log('[Mock Concept] 获取概念相关股票:', { conceptId, limit }); // 生成模拟股票数据(确保 change_pct 是数字类型) const stocks = []; for (let i = 0; i < limit; i++) { const code = 600000 + i; stocks.push({ stock_code: `${code}.SH`, code: `${code}.SH`, stock_name: `股票${i + 1}`, name: `股票${i + 1}`, change_pct: parseFloat((Math.random() * 10 - 2).toFixed(2)), price: parseFloat((Math.random() * 100 + 10).toFixed(2)), market_cap: parseFloat((Math.random() * 1000 + 100).toFixed(2)), reason: '板块核心成分股' }); } return HttpResponse.json({ stocks, total: stocks.length, concept_id: conceptId }); }), // 获取概念相关股票(/api/concept 路由 - 热点概览异动列表使用) http.get('/api/concept/:conceptId/stocks', async ({ params, request }) => { await delay(200); const { conceptId } = params; const url = new URL(request.url); const limit = parseInt(url.searchParams.get('limit') || '15'); console.log('[Mock Concept] /api/concept/:conceptId/stocks:', { conceptId, limit }); // 股票池 const stockPool = [ { code: '600519', name: '贵州茅台' }, { code: '300750', name: '宁德时代' }, { code: '601318', name: '中国平安' }, { code: '002594', name: '比亚迪' }, { code: '601012', name: '隆基绿能' }, { code: '300274', name: '阳光电源' }, { code: '688981', name: '中芯国际' }, { code: '000725', name: '京东方A' }, { code: '002230', name: '科大讯飞' }, { code: '300124', name: '汇川技术' }, { code: '002049', name: '紫光国微' }, { code: '688012', name: '中微公司' }, { code: '603501', name: '韦尔股份' }, { code: '600036', name: '招商银行' }, { code: '000858', name: '五粮液' }, ]; // 生成模拟股票数据(确保 change_pct 是数字类型) const stocks = []; const count = Math.min(limit, stockPool.length); for (let i = 0; i < count; i++) { const stock = stockPool[i]; // 根据股票代码判断交易所后缀 let suffix = '.SZ'; if (stock.code.startsWith('6')) { suffix = '.SH'; } else if (stock.code.startsWith('8') || stock.code.startsWith('9') || stock.code.startsWith('4')) { suffix = '.BJ'; } stocks.push({ stock_code: `${stock.code}${suffix}`, code: `${stock.code}${suffix}`, stock_name: stock.name, name: stock.name, change_pct: parseFloat((Math.random() * 12 - 3).toFixed(2)), // -3% ~ +9% price: parseFloat((Math.random() * 100 + 10).toFixed(2)), market_cap: parseFloat((Math.random() * 1000 + 100).toFixed(2)), reason: '板块核心标的' }); } return HttpResponse.json({ success: true, data: { stocks, total: stocks.length, concept_id: conceptId } }); }), // 获取最新交易日期 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, ''); console.log('[Mock Concept] 获取最新交易日期:', dateStr); return HttpResponse.json({ latest_date: dateStr, timestamp: today.toISOString() }); }), // 搜索概念(硬编码 URL) http.post('http://111.198.58.126:16801/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] 搜索概念 (硬编码URL):', { 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] 搜索失败:', 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); const url = new URL(request.url); const minStockCount = parseInt(url.searchParams.get('min_stock_count') || '3'); const days = parseInt(url.searchParams.get('days') || '7'); const startDate = url.searchParams.get('start_date'); const endDate = url.searchParams.get('end_date'); console.log('[Mock Concept] 获取统计数据 (直接API):', { minStockCount, days, startDate, endDate }); // 生成完整的统计数据 const statsData = generateConceptStats(); return HttpResponse.json({ success: true, data: statsData, note: 'Mock 数据', params: { min_stock_count: minStockCount, days: days, start_date: startDate, end_date: endDate }, updated_at: new Date().toISOString() }); }), // 获取统计数据(通过 nginx 代理) http.get('/concept-api/statistics', async ({ request }) => { await delay(300); const url = new URL(request.url); const minStockCount = parseInt(url.searchParams.get('min_stock_count') || '3'); const days = parseInt(url.searchParams.get('days') || '7'); const startDate = url.searchParams.get('start_date'); const endDate = url.searchParams.get('end_date'); console.log('[Mock Concept] 获取统计数据 (nginx代理):', { minStockCount, days, startDate, endDate }); // 生成完整的统计数据 const statsData = generateConceptStats(); return HttpResponse.json({ success: true, data: statsData, note: 'Mock 数据(通过 nginx 代理)', params: { min_stock_count: minStockCount, days: days, start_date: startDate, end_date: endDate }, updated_at: new Date().toISOString() }); }), // 获取概念价格时间序列 http.get('http://111.198.58.126:16801/concept/:conceptId/price-timeseries', async ({ params, request }) => { await delay(300); const { conceptId } = params; const url = new URL(request.url); const startDate = url.searchParams.get('start_date'); const endDate = url.searchParams.get('end_date'); console.log('[Mock Concept] 获取价格时间序列:', { conceptId, startDate, endDate }); // 生成时间序列数据 const timeseries = []; const start = new Date(startDate || '2024-01-01'); const end = new Date(endDate || new Date()); const daysDiff = Math.ceil((end - start) / (1000 * 60 * 60 * 24)); for (let i = 0; i <= daysDiff; i++) { const date = new Date(start); date.setDate(date.getDate() + i); // 跳过周末 if (date.getDay() !== 0 && date.getDay() !== 6) { timeseries.push({ trade_date: date.toISOString().split('T')[0], // 改为 trade_date avg_change_pct: parseFloat((Math.random() * 8 - 2).toFixed(2)), // 转为数值 stock_count: Math.floor(Math.random() * 30) + 10, volume: Math.floor(Math.random() * 1000000000) }); } } return HttpResponse.json({ concept_id: conceptId, timeseries: timeseries, start_date: startDate, end_date: endDate }); }), // 获取概念相关新闻 (search_china_news) http.get('http://111.198.58.126:21891/search_china_news', async ({ request }) => { await delay(300); const url = new URL(request.url); const query = url.searchParams.get('query'); const exactMatch = url.searchParams.get('exact_match'); const startDate = url.searchParams.get('start_date'); const endDate = url.searchParams.get('end_date'); const topK = parseInt(url.searchParams.get('top_k') || '100'); console.log('[Mock Concept] 搜索中国新闻:', { query, exactMatch, startDate, endDate, topK }); // 生成新闻数据 const news = []; const newsCount = Math.min(topK, Math.floor(Math.random() * 15) + 5); // 5-20 条新闻 for (let i = 0; i < newsCount; i++) { const daysAgo = Math.floor(Math.random() * 100); // 0-100 天前 const date = new Date(); date.setDate(date.getDate() - daysAgo); const hour = Math.floor(Math.random() * 24); const minute = Math.floor(Math.random() * 60); const publishedTime = `${date.toISOString().split('T')[0]} ${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}:00`; news.push({ id: `news_${i}`, title: `${query || '概念'}板块动态:${['利好政策发布', '行业景气度提升', '龙头企业业绩超预期', '技术突破进展', '市场需求旺盛'][i % 5]}`, detail: `${query || '概念'}相关新闻详细内容。近期${query || '概念'}板块表现活跃,市场关注度持续上升。多家券商研报指出,${query || '概念'}行业前景广阔,建议重点关注龙头企业投资机会。`, description: `${query || '概念'}板块最新动态摘要...`, source: ['新浪财经', '东方财富网', '财联社', '证券时报', '中国证券报', '上海证券报'][Math.floor(Math.random() * 6)], published_time: publishedTime, url: `https://finance.sina.com.cn/stock/news/${date.getFullYear()}${String(date.getMonth() + 1).padStart(2, '0')}${String(date.getDate()).padStart(2, '0')}/news_${i}.html` }); } // 按时间降序排序 news.sort((a, b) => new Date(b.published_time) - new Date(a.published_time)); // 返回数组(不是对象) return HttpResponse.json(news); }), // 获取概念相关研报 (search) http.get('http://111.198.58.126:8811/search', async ({ request }) => { await delay(300); const url = new URL(request.url); const query = url.searchParams.get('query'); const mode = url.searchParams.get('mode'); const exactMatch = url.searchParams.get('exact_match'); const size = parseInt(url.searchParams.get('size') || '30'); const startDate = url.searchParams.get('start_date'); console.log('[Mock Concept] 搜索研报:', { query, mode, exactMatch, size, startDate }); // 生成研报数据 const reports = []; const reportCount = Math.min(size, Math.floor(Math.random() * 10) + 3); // 3-12 份研报 const publishers = ['中信证券', '国泰君安', '华泰证券', '招商证券', '海通证券', '广发证券', '申万宏源', '兴业证券']; const authors = ['张明', '李华', '王强', '刘洋', '陈杰', '赵敏']; const ratings = ['买入', '增持', '中性', '减持', '强烈推荐']; const securityNames = ['行业研究', '公司研究', '策略研究', '宏观研究', '固收研究']; for (let i = 0; i < reportCount; i++) { const daysAgo = Math.floor(Math.random() * 100); // 0-100 天前 const date = new Date(); date.setDate(date.getDate() - daysAgo); const declareDate = `${date.toISOString().split('T')[0]} ${String(Math.floor(Math.random() * 24)).padStart(2, '0')}:${String(Math.floor(Math.random() * 60)).padStart(2, '0')}:00`; reports.push({ id: `report_${i}`, report_title: `${query || '概念'}行业${['深度研究报告', '投资策略分析', '行业景气度跟踪', '估值分析报告', '竞争格局研究'][i % 5]}`, content: `${query || '概念'}行业研究报告内容摘要。\n\n核心观点:\n1. ${query || '概念'}行业景气度持续向好,市场规模预计将保持高速增长。\n2. 龙头企业凭借技术优势和规模效应,市场份额有望进一步提升。\n3. 政策支持力度加大,为行业发展提供有力保障。\n\n投资建议:建议重点关注行业龙头企业,给予"${ratings[Math.floor(Math.random() * ratings.length)]}"评级。`, abstract: `本报告深入分析了${query || '概念'}行业的发展趋势、竞争格局和投资机会,认为行业具备良好的成长性...`, publisher: publishers[Math.floor(Math.random() * publishers.length)], author: authors[Math.floor(Math.random() * authors.length)], declare_date: declareDate, rating: ratings[Math.floor(Math.random() * ratings.length)], security_name: securityNames[Math.floor(Math.random() * securityNames.length)], content_url: `https://pdf.dfcfw.com/pdf/H3_${1000000 + i}_1_${date.getFullYear()}${String(date.getMonth() + 1).padStart(2, '0')}${String(date.getDate()).padStart(2, '0')}.pdf` }); } // 按时间降序排序 reports.sort((a, b) => new Date(b.declare_date) - new Date(a.declare_date)); // 返回符合组件期望的格式 return HttpResponse.json({ results: reports, total: reports.length, query: query, mode: mode }); }), // ============ 层级结构 API ============ // 获取完整层级结构 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一体机'] }, { 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: 'lv2_1_2', name: 'AI模型与软件', concept_count: 13, concepts: ['DeepSeek', 'KIMI', 'SORA概念', '国产大模型'] }, { id: 'lv2_1_3', name: 'AI应用', concept_count: 17, 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: 'lv1_2', name: '半导体', concept_count: 45, 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: 'lv1_3', name: '机器人', concept_count: 42, 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: 'lv1_4', name: '消费电子', concept_count: 38, 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: 'lv1_5', name: '智能驾驶与汽车', concept_count: 35, 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: 'lv1_6', name: '新能源与电力', concept_count: 52, 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: 'lv1_7', name: '空天经济', concept_count: 28, children: [ { id: 'lv2_7_1', name: '低空经济', concept_count: 14, concepts: ['低空经济', 'eVTOL', '飞行汽车'] }, { id: 'lv2_7_2', name: '商业航天', concept_count: 14, concepts: ['卫星互联网', '商业航天', '北斗导航'] } ] }, { id: 'lv1_8', 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: ['军贸', '巴黎航展'] } ] } ]; return HttpResponse.json({ hierarchy, total_lv1: hierarchy.length, total_concepts: hierarchy.reduce((acc, h) => acc + h.concept_count, 0) }); }), // 获取层级统计数据(包含涨跌幅) http.get('/concept-api/statistics/hierarchy', async () => { await delay(300); console.log('[Mock Concept] 获取层级统计数据'); const statistics = [ { lv1: '人工智能', concept_count: 98, avg_change_pct: 3.56, top_gainer: 'DeepSeek', top_gainer_change: 15.23 }, { lv1: '半导体', concept_count: 45, avg_change_pct: 2.12, top_gainer: '光刻机', top_gainer_change: 8.76 }, { lv1: '机器人', concept_count: 42, avg_change_pct: 4.28, top_gainer: '人形机器人', top_gainer_change: 12.45 }, { lv1: '消费电子', concept_count: 38, avg_change_pct: 1.45, top_gainer: 'AR眼镜', top_gainer_change: 6.78 }, { lv1: '智能驾驶与汽车', concept_count: 35, avg_change_pct: 2.89, top_gainer: 'Robotaxi', top_gainer_change: 9.32 }, { lv1: '新能源与电力', concept_count: 52, avg_change_pct: -0.56, top_gainer: '固态电池', top_gainer_change: 5.67 }, { lv1: '空天经济', concept_count: 28, avg_change_pct: 3.12, top_gainer: '低空经济', top_gainer_change: 11.23 }, { lv1: '国防军工', concept_count: 25, avg_change_pct: 1.78, top_gainer: 'AI军工', top_gainer_change: 7.89 } ]; return HttpResponse.json({ statistics, total_lv1: statistics.length, total_concepts: statistics.reduce((acc, s) => acc + s.concept_count, 0), market_avg_change: 2.34, update_time: new Date().toISOString() }); }), // 获取层级涨跌幅数据(实时价格) http.get('/concept-api/hierarchy/price', async ({ request }) => { await delay(200); const url = new URL(request.url); const tradeDate = url.searchParams.get('trade_date'); console.log('[Mock Concept] 获取层级涨跌幅数据:', { 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 = [ // 人工智能下的 lv2 { 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 }, // 半导体下的 lv2 { 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 }, // 机器人下的 lv2 { 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 }, // 消费电子下的 lv2 { 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 }, // 智能驾驶下的 lv2 { 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 }, // 新能源下的 lv2 { 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 }, // 空天经济下的 lv2 { concept_name: '低空经济', avg_change_pct: 4.56, stock_count: 42 }, { concept_name: '商业航天', avg_change_pct: 1.89, stock_count: 34 }, // 国防军工下的 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 } ]; // 模拟 lv3 层级涨跌幅数据 const lv3_concepts = [ // AI基础设施下的 lv3 { 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 }, // AI应用下的 lv3 { concept_name: '智能体与陪伴', avg_change_pct: 3.12, stock_count: 24 }, { concept_name: '行业应用', avg_change_pct: 1.56, stock_count: 18 } ]; // 计算交易日期(如果没有传入则使用今天) 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, update_time: new Date().toISOString() }); }), // 获取指定层级的概念列表 http.get('/concept-api/hierarchy/:lv1Id', async ({ params, request }) => { await delay(300); const { lv1Id } = params; const url = new URL(request.url); const lv2Id = url.searchParams.get('lv2_id'); console.log('[Mock Concept] 获取层级概念列表:', { lv1Id, lv2Id }); // 返回该层级下的概念列表 let concepts = generatePopularConcepts(20); // 添加层级信息 concepts = concepts.map(c => ({ ...c, hierarchy: { lv1: '人工智能', lv1_id: lv1Id, lv2: lv2Id ? 'AI基础设施' : null, lv2_id: lv2Id } })); return HttpResponse.json({ concepts, total: concepts.length, lv1_id: lv1Id, lv2_id: lv2Id }); }), // 热门概念静态数据文件(HeroPanel 使用) http.get('/data/concept/latest.json', async () => { await delay(200); console.log('[Mock Concept] 获取热门概念静态数据'); const concepts = generatePopularConcepts(30); return HttpResponse.json({ date: new Date().toISOString().split('T')[0], results: concepts }); }) ];