diff --git a/src/mocks/handlers/event.js b/src/mocks/handlers/event.js index a20dc624..de4625c1 100644 --- a/src/mocks/handlers/event.js +++ b/src/mocks/handlers/event.js @@ -120,12 +120,14 @@ export const eventHandlers = [ try { const result = generateMockEvents(params); - // 返回格式兼容 NewsPanel 期望的结构 - // NewsPanel 期望: { success, data: [], pagination: {} } + // 返回格式兼容 useEventData 期望的结构 + // useEventData 期望: { success, data: { events: [], pagination: {} } } return HttpResponse.json({ success: true, - data: result.events, // 事件数组 - pagination: result.pagination, // 分页信息 + data: { + events: result.events, // 事件数组 + pagination: result.pagination // 分页信息 + }, message: '获取成功' }); } catch (error) { diff --git a/src/mocks/handlers/stock.js b/src/mocks/handlers/stock.js index f18ffcee..4a69472b 100644 --- a/src/mocks/handlers/stock.js +++ b/src/mocks/handlers/stock.js @@ -263,15 +263,15 @@ export const stockHandlers = [ try { let data; - if (type === 'timeline') { + if (type === 'timeline' || type === 'minute') { + // timeline 和 minute 都使用分时数据 data = generateTimelineData(indexCode); } else if (type === 'daily') { data = generateDailyData(indexCode, 30); } else { - return HttpResponse.json( - { error: '不支持的类型' }, - { status: 400 } - ); + // 其他类型也降级使用 timeline 数据 + console.log('[Mock Stock] 未知类型,降级使用 timeline:', type); + data = generateTimelineData(indexCode); } return HttpResponse.json({ @@ -558,4 +558,133 @@ export const stockHandlers = [ ); } }), + + // 获取股票详细行情(quote-detail) + http.get('/api/stock/:stockCode/quote-detail', async ({ params }) => { + await delay(200); + + const { stockCode } = params; + console.log('[Mock Stock] 获取股票详细行情:', { stockCode }); + + const stocks = generateStockList(); + const codeWithoutSuffix = stockCode.replace(/\.(SH|SZ)$/i, ''); + const stockInfo = stocks.find(s => s.code === codeWithoutSuffix); + const stockName = stockInfo?.name || `股票${stockCode}`; + + // 生成基础价格(10-200之间) + const basePrice = parseFloat((Math.random() * 190 + 10).toFixed(2)); + // 涨跌幅(-10% 到 +10%) + const changePercent = parseFloat((Math.random() * 20 - 10).toFixed(2)); + // 涨跌额 + const change = parseFloat((basePrice * changePercent / 100).toFixed(2)); + // 昨收 + const prevClose = parseFloat((basePrice - change).toFixed(2)); + + return HttpResponse.json({ + success: true, + data: { + stock_code: stockCode, + stock_name: stockName, + price: basePrice, + change: change, + change_percent: changePercent, + prev_close: prevClose, + open: parseFloat((prevClose * (1 + (Math.random() * 0.02 - 0.01))).toFixed(2)), + high: parseFloat((basePrice * (1 + Math.random() * 0.05)).toFixed(2)), + low: parseFloat((basePrice * (1 - Math.random() * 0.05)).toFixed(2)), + volume: Math.floor(Math.random() * 100000000), + amount: parseFloat((Math.random() * 10000000000).toFixed(2)), + turnover_rate: parseFloat((Math.random() * 10).toFixed(2)), + amplitude: parseFloat((Math.random() * 8).toFixed(2)), + market: stockCode.startsWith('6') ? 'SH' : 'SZ', + update_time: new Date().toISOString(), + // 买卖盘口 + bid1: parseFloat((basePrice * 0.998).toFixed(2)), + bid1_volume: Math.floor(Math.random() * 10000), + bid2: parseFloat((basePrice * 0.996).toFixed(2)), + bid2_volume: Math.floor(Math.random() * 10000), + bid3: parseFloat((basePrice * 0.994).toFixed(2)), + bid3_volume: Math.floor(Math.random() * 10000), + bid4: parseFloat((basePrice * 0.992).toFixed(2)), + bid4_volume: Math.floor(Math.random() * 10000), + bid5: parseFloat((basePrice * 0.990).toFixed(2)), + bid5_volume: Math.floor(Math.random() * 10000), + ask1: parseFloat((basePrice * 1.002).toFixed(2)), + ask1_volume: Math.floor(Math.random() * 10000), + ask2: parseFloat((basePrice * 1.004).toFixed(2)), + ask2_volume: Math.floor(Math.random() * 10000), + ask3: parseFloat((basePrice * 1.006).toFixed(2)), + ask3_volume: Math.floor(Math.random() * 10000), + ask4: parseFloat((basePrice * 1.008).toFixed(2)), + ask4_volume: Math.floor(Math.random() * 10000), + ask5: parseFloat((basePrice * 1.010).toFixed(2)), + ask5_volume: Math.floor(Math.random() * 10000), + // 关键指标 + pe: parseFloat((Math.random() * 50 + 5).toFixed(2)), + pb: parseFloat((Math.random() * 8 + 0.5).toFixed(2)), + eps: parseFloat((Math.random() * 5 + 0.1).toFixed(3)), + market_cap: `${(Math.random() * 5000 + 100).toFixed(0)}亿`, + circulating_market_cap: `${(Math.random() * 3000 + 50).toFixed(0)}亿`, + total_shares: `${(Math.random() * 100 + 10).toFixed(2)}亿`, + circulating_shares: `${(Math.random() * 80 + 5).toFixed(2)}亿`, + week52_high: parseFloat((basePrice * 1.3).toFixed(2)), + week52_low: parseFloat((basePrice * 0.7).toFixed(2)) + }, + message: '获取成功' + }); + }), + + // FlexScreen 行情数据 + http.get('/api/flex-screen/quotes', async ({ request }) => { + await delay(200); + + const url = new URL(request.url); + const codes = url.searchParams.get('codes')?.split(',') || []; + + console.log('[Mock Stock] 获取 FlexScreen 行情:', { codes }); + + // 默认主要指数 + const defaultIndices = ['000001', '399001', '399006']; + const targetCodes = codes.length > 0 ? codes : defaultIndices; + + const indexData = { + '000001': { name: '上证指数', basePrice: 3200 }, + '399001': { name: '深证成指', basePrice: 10500 }, + '399006': { name: '创业板指', basePrice: 2100 }, + '000300': { name: '沪深300', basePrice: 3800 }, + '000016': { name: '上证50', basePrice: 2600 }, + '000905': { name: '中证500', basePrice: 5800 }, + }; + + const quotesData = {}; + targetCodes.forEach(code => { + const codeWithoutSuffix = code.replace(/\.(SH|SZ)$/i, ''); + const info = indexData[codeWithoutSuffix] || { name: `指数${code}`, basePrice: 3000 }; + + const changePercent = parseFloat((Math.random() * 4 - 2).toFixed(2)); + const price = parseFloat((info.basePrice * (1 + changePercent / 100)).toFixed(2)); + const change = parseFloat((price - info.basePrice).toFixed(2)); + + quotesData[code] = { + code: code, + name: info.name, + price: price, + change: change, + change_percent: changePercent, + prev_close: info.basePrice, + open: parseFloat((info.basePrice * (1 + (Math.random() * 0.01 - 0.005))).toFixed(2)), + high: parseFloat((price * (1 + Math.random() * 0.01)).toFixed(2)), + low: parseFloat((price * (1 - Math.random() * 0.01)).toFixed(2)), + volume: parseFloat((Math.random() * 5000 + 2000).toFixed(2)), // 亿手 + amount: parseFloat((Math.random() * 8000 + 3000).toFixed(2)), // 亿元 + update_time: new Date().toISOString() + }; + }); + + return HttpResponse.json({ + success: true, + data: quotesData, + message: '获取成功' + }); + }), ];