From b4791cbd4d85d6e9f8d3d2e6188d2d1507abd624 Mon Sep 17 00:00:00 2001 From: zzlgreat Date: Wed, 10 Dec 2025 17:45:32 +0800 Subject: [PATCH] update pay ui --- src/mocks/handlers/concept.js | 73 ++++++++++++++++++++++++++++++++--- src/services/eventService.js | 42 ++++++++++++++++++-- 2 files changed, 106 insertions(+), 9 deletions(-) diff --git a/src/mocks/handlers/concept.js b/src/mocks/handlers/concept.js index ac8d1557..8a516bb4 100644 --- a/src/mocks/handlers/concept.js +++ b/src/mocks/handlers/concept.js @@ -240,7 +240,7 @@ export const conceptHandlers = [ } }), - // 获取概念相关股票 + // 获取概念相关股票(concept-api 路由) http.get('/concept-api/concepts/:conceptId/stocks', async ({ params, request }) => { await delay(300); @@ -250,15 +250,19 @@ export const conceptHandlers = [ 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: `${600000 + i}`, + stock_code: `${code}.SH`, + code: `${code}.SH`, stock_name: `股票${i + 1}`, - change_pct: (Math.random() * 10 - 2).toFixed(2), - price: (Math.random() * 100 + 10).toFixed(2), - market_cap: (Math.random() * 1000 + 100).toFixed(2) + 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: '板块核心成分股' }); } @@ -269,6 +273,63 @@ export const conceptHandlers = [ }); }), + // 获取概念相关股票(/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]; + const suffix = stock.code.startsWith('6') ? '.SH' : '.SZ'; + 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); diff --git a/src/services/eventService.js b/src/services/eventService.js index c0311bb4..5f8d386c 100755 --- a/src/services/eventService.js +++ b/src/services/eventService.js @@ -2,6 +2,37 @@ import { logger } from '../utils/logger'; +/** + * 格式化股票代码,确保包含交易所后缀 + * @param {string} code - 股票代码(可能带或不带后缀) + * @returns {string} 带后缀的股票代码 + */ +const formatStockCode = (code) => { + if (!code) return code; + + // 如果已经有后缀,直接返回 + if (code.includes('.')) { + return code; + } + + // 根据股票代码规则添加后缀 + // 6开头 -> 上海 .SH + // 0、3开头 -> 深圳 .SZ + // 688开头 -> 科创板(上海).SH + // 8开头(北交所)-> .BJ(暂不处理,大部分场景不需要) + const firstChar = code.charAt(0); + const prefix = code.substring(0, 3); + + if (firstChar === '6' || prefix === '688') { + return `${code}.SH`; + } else if (firstChar === '0' || firstChar === '3') { + return `${code}.SZ`; + } + + // 默认返回原代码(可能是指数或其他) + return code; +}; + const apiRequest = async (url, options = {}) => { const method = options.method || 'GET'; const requestData = options.body ? JSON.parse(options.body) : null; @@ -342,8 +373,10 @@ export const stockService = { params.append('event_time', eventTime); } - const url = `/api/stock/${stockCode}/kline?${params.toString()}`; - logger.debug('stockService', '获取K线数据', { stockCode, chartType, eventTime }); + // 格式化股票代码,确保带交易所后缀 + const formattedCode = formatStockCode(stockCode); + const url = `/api/stock/${formattedCode}/kline?${params.toString()}`; + logger.debug('stockService', '获取K线数据', { stockCode: formattedCode, chartType, eventTime }); const response = await apiRequest(url); @@ -371,8 +404,11 @@ export const stockService = { */ getBatchKlineData: async (stockCodes, chartType = 'timeline', eventTime = null, options = {}) => { try { + // 格式化所有股票代码,确保带交易所后缀 + const formattedCodes = stockCodes.map(code => formatStockCode(code)); + const requestBody = { - codes: stockCodes, + codes: formattedCodes, type: chartType }; if (eventTime) {