import React, { useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Card, Row, Col, Button, Select, Tag, Statistic, Alert, Spin } from 'antd'; import { ArrowUpOutlined, ArrowDownOutlined, LineChartOutlined, BarChartOutlined, AlertOutlined, CalculatorOutlined } from '@ant-design/icons'; import { fetchFutureDetail } from '../../store/futuresSlice'; import { useLocation, useNavigate } from 'react-router-dom'; import { generateKlineData, generateFutureData } from '../../utils/mockData'; import './Detail.css'; // 导入TradingView Lightweight Charts import { createChart } from 'lightweight-charts'; const { Option } = Select; const Detail = () => { const dispatch = useDispatch(); const navigate = useNavigate(); const location = useLocation(); const chartRef = useRef(null); const chartInstance = useRef(null); const { selectedFuture, loading, error } = useSelector(state => state.futures); const [timeframe, setTimeframe] = useState('1D'); const [localData, setLocalData] = useState(null); // 解析URL参数获取品种信息 const getQueryParams = () => { const params = new URLSearchParams(location.search); return { code: params.get('code') || 'MA', name: params.get('name') || '甲醇' }; }; const { code, name } = getQueryParams(); // 调试日志 console.log('Detail page loaded with:', { code, name }); useEffect(() => { // 尝试使用本地生成数据作为备选方案 const fallbackData = generateFutureData(code, name); setLocalData(fallbackData); console.log('Generated fallback data:', fallbackData); // 同时尝试从Redux获取数据 console.log('Dispatching fetchFutureDetail with:', { code, name }); dispatch(fetchFutureDetail({ code, name })); }, [dispatch, code, name]); useEffect(() => { // 初始化K线图表 const dataToUse = selectedFuture || localData; if (chartRef.current && dataToUse) { console.log('Initializing chart with data:', dataToUse); if (chartInstance.current) { chartInstance.current.destroy(); } const chart = createChart(chartRef.current, { width: chartRef.current.clientWidth, height: 400, layout: { backgroundColor: '#fff', textColor: '#262626' }, grid: { vertLines: { color: '#f0f0f0' }, horzLines: { color: '#f0f0f0' } }, priceScale: { borderColor: '#f0f0f0' }, timeScale: { borderColor: '#f0f0f0', timeVisible: true, secondsVisible: false } }); // 添加K线系列 const candlestickSeries = chart.addCandlestickSeries({ upColor: '#52c41a', downColor: '#ff4d4f', borderUpColor: '#52c41a', borderDownColor: '#ff4d4f', wickUpColor: '#52c41a', wickDownColor: '#ff4d4f' }); // 生成K线数据 const klineData = generateKlineData(30); candlestickSeries.setData(klineData); // 添加成交量系列 const volumeSeries = chart.addHistogramSeries({ color: '#82ca9d', lineWidth: 1, priceScaleId: '', scaleMargins: { top: 0.8, bottom: 0 } }); const volumeData = klineData.map(item => ({ time: item.time, value: item.volume, color: item.close >= item.open ? '#52c41a' : '#ff4d4f' })); volumeSeries.setData(volumeData); // 缩放到合适的范围 chart.timeScale().fitContent(); chartInstance.current = chart; // 响应窗口大小变化 const handleResize = () => { if (chartInstance.current) { chartInstance.current.resize(chartRef.current.clientWidth, 400); } }; window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); if (chartInstance.current) { chartInstance.current.destroy(); } }; } }, [selectedFuture, localData]); const handleBack = () => { navigate('/'); }; const getChangeColor = (changePercent) => { return changePercent >= 0 ? '#52c41a' : '#ff4d4f'; }; const getChangeIcon = (changePercent) => { return changePercent >= 0 ? : ; }; const getTrendColor = (direction) => { if (direction === '看多') return '#52c41a'; if (direction === '看空') return '#ff4d4f'; return '#faad14'; }; // 使用Redux数据或本地数据 const dataToDisplay = selectedFuture || localData; // 确保即使在加载状态下也能显示内容 console.log('Rendering Detail component with state:', { loading, selectedFuture, localData, error }); return (
{/* 页面头部 */}

{dataToDisplay ? dataToDisplay.fullName : `${name}-${code}`}

{/* 错误信息 */} {error && ( )} {/* 加载状态 */} {loading && !dataToDisplay && (
)} {/* 数据内容 */} {dataToDisplay && ( <> {/* 基本信息 */} 60 ? '#52c41a' : dataToDisplay.winRate > 40 ? '#faad14' : '#ff4d4f' }} /> {/* K线图表 */} K线图表
} className="detail-card" style={{ marginBottom: 24 }} >
{/* 多周期趋势分析 */} 多周期趋势分析} className="detail-card" style={{ marginBottom: 24 }} > {Object.entries(dataToDisplay.trends).map(([period, trend]) => (

{period}

{trend.direction}
{trend.status}
RSI: {trend.rsi}
))}
{/* 技术指标 */}
MACD
{dataToDisplay.indicators.macd}
RSI
{dataToDisplay.indicators.rsi}
布林带
{dataToDisplay.indicators.bollinger}
KDJ
{dataToDisplay.indicators.kdj}
{/* 交易建议 */} 交易建议} className="detail-card" style={{ marginBottom: 24 }} > {/* 风险评估 */} 风险评估} className="detail-card" >
风险等级
{dataToDisplay.riskLevel}
波动率
{dataToDisplay.volatility}
)} {/* 无数据状态 */} {!loading && !dataToDisplay && !error && (
)} ); }; export default Detail;