You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

352 lines
13 KiB

import React, { useState, useEffect } from 'react';
import { Card, Button, Row, Col, Select, Tabs, Tag, Statistic, Alert, Spin } from 'antd';
import { useParams, useNavigate } from 'react-router-dom';
import { LineChartOutlined, BarChartOutlined, AreaChartOutlined, ArrowUpOutlined, AlertOutlined, RobotOutlined, SafetyOutlined } from '@ant-design/icons';
import { generateFutureData } from '../../utils/mockData';
import './Detail.css';
const { Option } = Select;
const { TabPane } = Tabs;
const Detail = () => {
const navigate = useNavigate();
const { code } = useParams();
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [currentPeriod, setCurrentPeriod] = useState('1H');
const [currentIndicator, setCurrentIndicator] = useState('MA');
console.log('Detail page loaded with code:', code);
useEffect(() => {
// 模拟数据加载
setTimeout(() => {
const futureData = generateFutureData(code, '测试品种');
setData(futureData);
setLoading(false);
}, 500);
}, [code]);
const handleBack = () => {
navigate('/');
};
const handlePeriodChange = (value) => {
setCurrentPeriod(value);
};
const handleIndicatorChange = (value) => {
setCurrentIndicator(value);
};
if (loading) {
return (
<div className="loading-container">
<Spin size="large" tip="加载数据中..." />
</div>
);
}
if (!data) {
return (
<div className="error-container">
<Alert message="未找到品种数据" type="error" />
<Button type="primary" onClick={handleBack} style={{ marginTop: 16 }}>
返回主页
</Button>
</div>
);
}
return (
<div className="detail">
{/* 页面头部 */}
<div className="detail-header">
<Button type="default" onClick={handleBack} style={{ marginBottom: 16 }}>
返回主页
</Button>
<div className="header-info">
<h2>{data.name} ({data.code})</h2>
<div className="price-info">
<Statistic
title="当前价格"
value={data.currentPrice}
precision={2}
valueStyle={{ color: data.changePercent >= 0 ? '#52c41a' : '#ff4d4f' }}
/>
<Statistic
title="涨跌幅"
value={data.changePercent}
suffix="%"
valueStyle={{ color: data.changePercent >= 0 ? '#52c41a' : '#ff4d4f' }}
/>
<Statistic
title="胜率"
value={data.winRate}
suffix="%"
valueStyle={{ color: '#1890ff' }}
/>
</div>
</div>
</div>
{/* K线图表区 */}
<Card className="detail-card" style={{ marginBottom: 24 }}>
<div className="chart-header">
<div className="chart-title">
<h3>K线图表</h3>
<div className="chart-controls">
<span style={{ marginRight: 16 }}>周期:</span>
<Select
value={currentPeriod}
onChange={handlePeriodChange}
style={{ width: 120, marginRight: 16 }}
>
<Option value="5M">5分钟</Option>
<Option value="30M">30分钟</Option>
<Option value="1H">1小时</Option>
<Option value="1D">1</Option>
<Option value="1W">1</Option>
</Select>
<span style={{ marginRight: 16 }}>指标:</span>
<Select
value={currentIndicator}
onChange={handleIndicatorChange}
style={{ width: 120 }}
>
<Option value="MA">MA</Option>
<Option value="MACD">MACD</Option>
<Option value="KDJ">KDJ</Option>
<Option value="RSI">RSI</Option>
<Option value="BOLL">布林带</Option>
</Select>
</div>
</div>
</div>
<div className="kline-chart">
{/* 这里将集成TradingView Lightweight Charts */}
<div className="chart-placeholder">
<LineChartOutlined style={{ fontSize: 48, color: '#1890ff', marginBottom: 16 }} />
<p>K线图表区域</p>
<p>周期: {currentPeriod} | 指标: {currentIndicator}</p>
</div>
</div>
</Card>
{/* 技术指标区 */}
<Card className="detail-card" style={{ marginBottom: 24 }}>
<div className="section-header">
<h3>技术指标</h3>
<BarChartOutlined />
</div>
<Row gutter={[16, 16]}>
<Col xs={24} sm={12} md={8} lg={6}>
<div className="indicator-item">
<div className="indicator-label">MA5</div>
<div className="indicator-value">{data.technicalIndicators?.ma5 || 'N/A'}</div>
</div>
</Col>
<Col xs={24} sm={12} md={8} lg={6}>
<div className="indicator-item">
<div className="indicator-label">MA10</div>
<div className="indicator-value">{data.technicalIndicators?.ma10 || 'N/A'}</div>
</div>
</Col>
<Col xs={24} sm={12} md={8} lg={6}>
<div className="indicator-item">
<div className="indicator-label">MACD</div>
<div className="indicator-value">{data.technicalIndicators?.macd || 'N/A'}</div>
</div>
</Col>
<Col xs={24} sm={12} md={8} lg={6}>
<div className="indicator-item">
<div className="indicator-label">RSI</div>
<div className="indicator-value">{data.technicalIndicators?.rsi || 'N/A'}</div>
</div>
</Col>
<Col xs={24} sm={12} md={8} lg={6}>
<div className="indicator-item">
<div className="indicator-label">KDJ</div>
<div className="indicator-value">{data.technicalIndicators?.kdj || 'N/A'}</div>
</div>
</Col>
<Col xs={24} sm={12} md={8} lg={6}>
<div className="indicator-item">
<div className="indicator-label">布林带</div>
<div className="indicator-value">{data.technicalIndicators?.bollinger || 'N/A'}</div>
</div>
</Col>
<Col xs={24} sm={12} md={8} lg={6}>
<div className="indicator-item">
<div className="indicator-label">ATR</div>
<div className="indicator-value">{data.atr}</div>
</div>
</Col>
<Col xs={24} sm={12} md={8} lg={6}>
<div className="indicator-item">
<div className="indicator-label">ADX</div>
<div className="indicator-value">{data.adx}</div>
</div>
</Col>
</Row>
</Card>
{/* 多周期趋势和AI研判区 */}
<Row gutter={[16, 16]} style={{ marginBottom: 24 }}>
{/* 多周期趋势 */}
<Col xs={24} lg={12}>
<Card className="detail-card">
<div className="section-header">
<h3>多周期趋势</h3>
<AreaChartOutlined />
</div>
<Row gutter={[16, 16]}>
{data.trends && Object.entries(data.trends).map(([period, trend]) => (
<Col xs={12} sm={6} key={period}>
<div className="trend-card">
<div className="trend-header">
<h4>{period.replace('MIN', 'min').replace('HOUR', 'min')}</h4>
<Tag color={trend.direction === '看多' ? 'green' : trend.direction === '看空' ? 'red' : 'orange'}>
{trend.direction}
</Tag>
</div>
<div className="trend-status">{trend.status}</div>
<div className="trend-rsi">RSI: {trend.rsi}</div>
</div>
</Col>
))}
</Row>
</Card>
</Col>
{/* AI研判区 */}
<Col xs={24} lg={12}>
<Card className="detail-card">
<div className="section-header">
<h3>AI研判</h3>
<RobotOutlined />
</div>
<div className="ai-analysis">
<div className="ai-overview">
<Statistic
title="趋势预测"
value={data.aiPrediction?.trend || '中性'}
valueStyle={{ color: data.aiPrediction?.trend === '上涨' ? '#52c41a' : data.aiPrediction?.trend === '下跌' ? '#ff4d4f' : '#1890ff' }}
/>
<Statistic
title="预测胜率"
value={data.aiPrediction?.winRate || 0}
suffix="%"
valueStyle={{ color: '#1890ff' }}
/>
<Statistic
title="预期收益"
value={data.aiPrediction?.expectedReturn || 0}
suffix="%"
valueStyle={{ color: '#52c41a' }}
/>
</div>
<div className="ai-details">
<h4>AI分析</h4>
<p>{data.aiAnalysis || 'AI正在分析中...'}</p>
<h4>关键因素</h4>
<div className="factor-tags">
{data.aiPrediction?.keyFactors?.map((factor, index) => (
<Tag key={index} color="blue">{factor}</Tag>
))}
</div>
</div>
</div>
</Card>
</Col>
</Row>
{/* 交易建议区和风险评估区 */}
<Row gutter={[16, 16]} style={{ marginBottom: 24 }}>
{/* 交易建议区 */}
<Col xs={24} lg={12}>
<Card className="detail-card">
<div className="section-header">
<h3>交易建议</h3>
<ArrowUpOutlined />
</div>
<div className="trading-advice">
<Row gutter={[16, 16]}>
<Col xs={24} sm={8}>
<div className="advice-item">
<div className="advice-label">入场价</div>
<div className="advice-value">{data.tradingAdvice?.entryPrice || 'N/A'}</div>
</div>
</Col>
<Col xs={24} sm={8}>
<div className="advice-item">
<div className="advice-label">止损价</div>
<div className="advice-value" style={{ color: '#ff4d4f' }}>
{data.tradingAdvice?.stopLoss || 'N/A'}
</div>
</div>
</Col>
<Col xs={24} sm={8}>
<div className="advice-item">
<div className="advice-label">目标价</div>
<div className="advice-value" style={{ color: '#52c41a' }}>
{data.tradingAdvice?.targetPrice || 'N/A'}
</div>
</div>
</Col>
</Row>
<div className="advice-details">
<h4>操作建议</h4>
<p>{data.tradingAdvice?.strategy || 'AI正在生成策略...'}</p>
</div>
</div>
</Card>
</Col>
{/* 风险评估区 */}
<Col xs={24} lg={12}>
<Card className="detail-card">
<div className="section-header">
<h3>风险评估</h3>
<SafetyOutlined />
</div>
<div className="risk-assessment">
<Row gutter={[16, 16]}>
<Col xs={24} sm={8}>
<div className="risk-item">
<div className="risk-label">风险等级</div>
<Tag color={data.riskLevel === '高' ? 'red' : data.riskLevel === '中等' ? 'orange' : 'green'}>
{data.riskLevel}
</Tag>
</div>
</Col>
<Col xs={24} sm={8}>
<div className="risk-item">
<div className="risk-label">波动率</div>
<div className="risk-value">{data.volatility || 'N/A'}%</div>
</div>
</Col>
<Col xs={24} sm={8}>
<div className="risk-item">
<div className="risk-label">最大回撤</div>
<div className="risk-value">{data.maxDrawdown || 'N/A'}%</div>
</div>
</Col>
</Row>
<div className="risk-details">
<h4>风险提示</h4>
<Alert
message={data.riskAlert || '无明显风险'}
type={data.riskLevel === '高' ? 'error' : data.riskLevel === '中等' ? 'warning' : 'info'}
showIcon
/>
</div>
</div>
</Card>
</Col>
</Row>
</div>
);
};
export default Detail;