// src/views/Company/hooks/useStockQuote.js // 股票行情数据获取 Hook import { useState, useEffect } from 'react'; import { stockService } from '@services/eventService'; import { logger } from '@utils/logger'; /** * 将 API 响应数据转换为 StockQuoteCard 所需格式 */ const transformQuoteData = (apiData, stockCode) => { if (!apiData) return null; return { // 基础信息 name: apiData.name || apiData.stock_name || '未知', code: apiData.code || apiData.stock_code || stockCode, indexTags: apiData.index_tags || apiData.indexTags || [], industry: apiData.industry || apiData.sw_industry_l2 || '', industryL1: apiData.industry_l1 || apiData.sw_industry_l1 || '', // 价格信息 currentPrice: apiData.current_price || apiData.currentPrice || apiData.close || 0, changePercent: apiData.change_percent || apiData.changePercent || apiData.pct_chg || 0, todayOpen: apiData.today_open || apiData.todayOpen || apiData.open || 0, yesterdayClose: apiData.yesterday_close || apiData.yesterdayClose || apiData.pre_close || 0, todayHigh: apiData.today_high || apiData.todayHigh || apiData.high || 0, todayLow: apiData.today_low || apiData.todayLow || apiData.low || 0, // 关键指标 pe: apiData.pe || apiData.pe_ttm || 0, eps: apiData.eps || apiData.basic_eps || undefined, pb: apiData.pb || apiData.pb_mrq || 0, marketCap: apiData.market_cap || apiData.marketCap || apiData.circ_mv || '0', week52Low: apiData.week52_low || apiData.week52Low || 0, week52High: apiData.week52_high || apiData.week52High || 0, // 主力动态 mainNetInflow: apiData.main_net_inflow || apiData.mainNetInflow || 0, institutionHolding: apiData.institution_holding || apiData.institutionHolding || 0, buyRatio: apiData.buy_ratio || apiData.buyRatio || 50, sellRatio: apiData.sell_ratio || apiData.sellRatio || 50, // 更新时间 updateTime: apiData.update_time || apiData.updateTime || new Date().toLocaleString(), }; }; /** * 股票行情数据获取 Hook * * @param {string} stockCode - 股票代码 * @returns {Object} { data, isLoading, error, refetch } */ export const useStockQuote = (stockCode) => { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); useEffect(() => { if (!stockCode) { setData(null); return; } const fetchQuote = async () => { setIsLoading(true); setError(null); try { logger.debug('useStockQuote', '获取股票行情', { stockCode }); const quotes = await stockService.getQuotes([stockCode]); // API 返回格式: { [stockCode]: quoteData } const quoteData = quotes?.[stockCode] || quotes; const transformedData = transformQuoteData(quoteData, stockCode); logger.debug('useStockQuote', '行情数据转换完成', { stockCode, hasData: !!transformedData }); setData(transformedData); } catch (err) { logger.error('useStockQuote', '获取行情失败', err); setError(err); setData(null); } finally { setIsLoading(false); } }; fetchQuote(); }, [stockCode]); // 手动刷新 const refetch = () => { if (stockCode) { setData(null); // 触发 useEffect 重新执行 } }; return { data, isLoading, error, refetch }; }; export default useStockQuote;