From ac7a6991bcafaa62de99b1eec04b3fb5077be1b8 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Wed, 29 Oct 2025 18:43:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0mock=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mocks/handlers/concept.js | 185 ++++++++++++++++++++++++++++++++++ src/mocks/handlers/event.js | 74 ++++++++++++++ 2 files changed, 259 insertions(+) diff --git a/src/mocks/handlers/concept.js b/src/mocks/handlers/concept.js index 310449f6..1dd57442 100644 --- a/src/mocks/handlers/concept.js +++ b/src/mocks/handlers/concept.js @@ -155,5 +155,190 @@ export const conceptHandlers = [ 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 } + ); + } + }), + + // 获取统计数据 + 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'); + + console.log('[Mock Concept] 获取统计数据:', { minStockCount, days }); + + return HttpResponse.json({ + total_concepts: 150, + active_concepts: 120, + avg_stock_count: 25, + top_concepts: generatePopularConcepts(10), + min_stock_count: minStockCount, + days: days, + 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({ + date: date.toISOString().split('T')[0], + avg_change_pct: (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 + }); + }), + + // 获取概念相关新闻 + http.get('http://111.198.58.126:21891/news', async ({ request }) => { + await delay(300); + + const url = new URL(request.url); + const conceptName = url.searchParams.get('concept_name'); + const startDate = url.searchParams.get('start_date'); + const endDate = url.searchParams.get('end_date'); + + console.log('[Mock Concept] 获取概念新闻:', { conceptName, startDate, endDate }); + + const news = []; + for (let i = 0; i < 10; i++) { + const date = new Date(); + date.setDate(date.getDate() - i); + + news.push({ + id: `news_${i}`, + title: `${conceptName || '概念'}相关新闻标题 ${i + 1}`, + content: `这是关于${conceptName || '概念'}的新闻内容摘要...`, + source: ['新浪财经', '东方财富', '财联社', '证券时报'][Math.floor(Math.random() * 4)], + publish_time: date.toISOString(), + url: `https://example.com/news/${i}` + }); + } + + return HttpResponse.json({ + news: news, + total: news.length, + concept_name: conceptName + }); + }), + + // 获取概念相关研报 + http.get('http://111.198.58.126:8811/reports', async ({ request }) => { + await delay(300); + + const url = new URL(request.url); + const conceptName = url.searchParams.get('concept_name'); + const startDate = url.searchParams.get('start_date'); + const endDate = url.searchParams.get('end_date'); + + console.log('[Mock Concept] 获取概念研报:', { conceptName, startDate, endDate }); + + const reports = []; + for (let i = 0; i < 5; i++) { + const date = new Date(); + date.setDate(date.getDate() - i * 2); + + reports.push({ + id: `report_${i}`, + title: `${conceptName || '概念'}行业研究报告 ${i + 1}`, + abstract: `本报告深入分析了${conceptName || '概念'}行业的发展趋势和投资机会...`, + author: ['中信证券', '国泰君安', '华泰证券', '招商证券'][Math.floor(Math.random() * 4)], + publish_time: date.toISOString(), + rating: ['买入', '增持', '中性'][Math.floor(Math.random() * 3)], + url: `https://example.com/report/${i}` + }); + } + + return HttpResponse.json({ + reports: reports, + total: reports.length, + concept_name: conceptName + }); }) ]; diff --git a/src/mocks/handlers/event.js b/src/mocks/handlers/event.js index 3869ff4d..91daa8e0 100644 --- a/src/mocks/handlers/event.js +++ b/src/mocks/handlers/event.js @@ -923,4 +923,78 @@ export const eventHandlers = [ } }); }), + + // ==================== 历史事件对比相关 ==================== + + // 获取历史事件相关股票 + http.get('/api/historical-events/:eventId/stocks', async ({ params }) => { + await delay(500); + + const { eventId } = params; + + console.log('[Mock] 获取历史事件相关股票, eventId:', eventId); + + // 生成历史事件相关股票数据 + const generateHistoricalEventStocks = (count = 10) => { + const stocks = []; + const sectors = ['半导体', '新能源', '医药', '消费电子', '人工智能', '5G通信']; + const stockNames = [ + '中芯国际', '长江存储', '华为海思', '紫光国微', '兆易创新', + '宁德时代', '比亚迪', '隆基绿能', '阳光电源', '亿纬锂能', + '恒瑞医药', '迈瑞医疗', '药明康德', '泰格医药', '康龙化成', + '立讯精密', '歌尔声学', '京东方A', 'TCL科技', '海康威视', + '科大讯飞', '商汤科技', '寒武纪', '海光信息', '中兴通讯' + ]; + + for (let i = 0; i < count; i++) { + const stockCode = `${Math.random() > 0.5 ? '6' : '0'}${String(Math.floor(Math.random() * 100000)).padStart(5, '0')}`; + const changePct = (Math.random() * 15 - 3).toFixed(2); // -3% ~ +12% + const correlation = (Math.random() * 0.4 + 0.6).toFixed(2); // 0.6 ~ 1.0 + + stocks.push({ + id: `stock_${i}`, + stock_code: `${stockCode}.${Math.random() > 0.5 ? 'SH' : 'SZ'}`, + stock_name: stockNames[i % stockNames.length], + sector: sectors[Math.floor(Math.random() * sectors.length)], + correlation: parseFloat(correlation), + event_day_change_pct: parseFloat(changePct), + relation_desc: { + data: [ + { + query_part: `该公司是${sectors[Math.floor(Math.random() * sectors.length)]}行业龙头,受事件影响显著,市场关注度高,订单量同比增长${Math.floor(Math.random() * 50 + 20)}%`, + sentences: `根据行业研究报告,该公司在${sectors[Math.floor(Math.random() * sectors.length)]}领域具有核心技术优势,产能利用率达到${Math.floor(Math.random() * 20 + 80)}%,随着事件的深入发展,公司业绩有望持续受益。机构预测未来三年复合增长率将达到${Math.floor(Math.random() * 30 + 15)}%以上`, + match_score: correlation > 0.8 ? '好' : (correlation > 0.6 ? '中' : '一般'), + author: ['中信证券', '国泰君安', '华泰证券', '招商证券'][Math.floor(Math.random() * 4)], + declare_date: new Date(Date.now() - Math.floor(Math.random() * 90) * 24 * 60 * 60 * 1000).toISOString(), + report_title: `${stockNames[i % stockNames.length]}深度研究报告` + } + ] + } + }); + } + + // 按相关度降序排序 + return stocks.sort((a, b) => b.correlation - a.correlation); + }; + + try { + const stocks = generateHistoricalEventStocks(15); + + return HttpResponse.json({ + success: true, + data: stocks, + message: '获取历史事件相关股票成功' + }); + } catch (error) { + console.error('[Mock] 获取历史事件相关股票失败:', error); + return HttpResponse.json( + { + success: false, + error: '获取历史事件相关股票失败', + data: [] + }, + { status: 500 } + ); + } + }), ];