fix: 修复卡片样式

master
Lxy 3 months ago
parent 578e88dbf0
commit f19d765d5f

@ -167,21 +167,28 @@
} }
/* 当前价格和支撑压力位 */ /* 当前价格和支撑压力位 */
.future-price-container-new {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.future-price-new { .future-price-new {
font-size: 24px; font-size: 24px;
font-weight: bold; font-weight: bold;
margin-bottom: 12px;
} }
.future-levels-new { .future-levels-new {
display: flex; display: flex;
justify-content: space-between; flex-direction: column;
margin-bottom: 16px; align-items: flex-end;
font-size: 14px; font-size: 12px;
color: #262626; color: #8c8c8c;
} }
.level-label-new { .level-label-new {
margin-bottom: 4px;
} }
/* 多周期趋势 */ /* 多周期趋势 */

@ -242,6 +242,7 @@ const Dashboard = () => {
</div> </div>
{/* 当前价格和支撑压力位 */} {/* 当前价格和支撑压力位 */}
<div className="future-price-container-new">
<div className="future-price-new" style={{ color: getChangeColor(item.changePercent) }}> <div className="future-price-new" style={{ color: getChangeColor(item.changePercent) }}>
{item.currentPrice.toFixed(2)} {item.currentPrice.toFixed(2)}
</div> </div>
@ -249,6 +250,7 @@ const Dashboard = () => {
<span className="level-label-new">支撑: {item.tradingAdvice?.support?.toFixed(2) || '-'}</span> <span className="level-label-new">支撑: {item.tradingAdvice?.support?.toFixed(2) || '-'}</span>
<span className="level-label-new">压力: {item.tradingAdvice?.resistance?.toFixed(2) || '-'}</span> <span className="level-label-new">压力: {item.tradingAdvice?.resistance?.toFixed(2) || '-'}</span>
</div> </div>
</div>
{/* 多周期趋势 */} {/* 多周期趋势 */}
<div className="future-trend-title-new"> <div className="future-trend-title-new">

@ -4,7 +4,7 @@ import { Card, Row, Col, Button, Select, Tag, Statistic, Alert, Spin } from 'ant
import { ArrowUpOutlined, ArrowDownOutlined, LineChartOutlined, BarChartOutlined, AlertOutlined, CalculatorOutlined } from '@ant-design/icons'; import { ArrowUpOutlined, ArrowDownOutlined, LineChartOutlined, BarChartOutlined, AlertOutlined, CalculatorOutlined } from '@ant-design/icons';
import { fetchFutureDetail } from '../../store/futuresSlice'; import { fetchFutureDetail } from '../../store/futuresSlice';
import { useLocation, useNavigate } from 'react-router-dom'; import { useLocation, useNavigate } from 'react-router-dom';
import { generateKlineData } from '../../utils/mockData'; import { generateKlineData, generateFutureData } from '../../utils/mockData';
import './Detail.css'; import './Detail.css';
// TradingView Lightweight Charts // TradingView Lightweight Charts
@ -18,8 +18,9 @@ const Detail = () => {
const location = useLocation(); const location = useLocation();
const chartRef = useRef(null); const chartRef = useRef(null);
const chartInstance = useRef(null); const chartInstance = useRef(null);
const { selectedFuture, loading } = useSelector(state => state.futures); const { selectedFuture, loading, error } = useSelector(state => state.futures);
const [timeframe, setTimeframe] = useState('1D'); const [timeframe, setTimeframe] = useState('1D');
const [localData, setLocalData] = useState(null);
// URL // URL
const getQueryParams = () => { const getQueryParams = () => {
@ -32,14 +33,25 @@ const Detail = () => {
const { code, name } = getQueryParams(); const { code, name } = getQueryParams();
//
console.log('Detail page loaded with:', { code, name });
useEffect(() => { 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(fetchFutureDetail({ code, name }));
}, [dispatch, code, name]); }, [dispatch, code, name]);
useEffect(() => { useEffect(() => {
// K线 // K线
if (chartRef.current && selectedFuture) { const dataToUse = selectedFuture || localData;
if (chartRef.current && dataToUse) {
console.log('Initializing chart with data:', dataToUse);
if (chartInstance.current) { if (chartInstance.current) {
chartInstance.current.destroy(); chartInstance.current.destroy();
} }
@ -122,7 +134,7 @@ const Detail = () => {
} }
}; };
} }
}, [selectedFuture]); }, [selectedFuture, localData]);
const handleBack = () => { const handleBack = () => {
navigate('/'); navigate('/');
@ -142,24 +154,11 @@ const Detail = () => {
return '#faad14'; return '#faad14';
}; };
if (loading) { // 使Redux
return ( const dataToDisplay = selectedFuture || localData;
<div className="loading-container">
<Spin size="large" tip="加载数据中..." />
</div>
);
}
if (!selectedFuture) { // 使
return ( console.log('Rendering Detail component with state:', { loading, selectedFuture, localData, error });
<div className="error-container">
<Alert message="未找到品种数据" type="error" />
<Button type="primary" onClick={handleBack} style={{ marginTop: 16 }}>
返回主页
</Button>
</div>
);
}
return ( return (
<div className="detail"> <div className="detail">
@ -168,54 +167,69 @@ const Detail = () => {
<Button type="default" onClick={handleBack} style={{ marginBottom: 16 }}> <Button type="default" onClick={handleBack} style={{ marginBottom: 16 }}>
返回主页 返回主页
</Button> </Button>
<h2>{selectedFuture.fullName}</h2> <h2>{dataToDisplay ? dataToDisplay.fullName : `${name}-${code}`}</h2>
</div>
{/* 错误信息 */}
{error && (
<Alert message="加载失败" description={error} type="error" showIcon style={{ marginBottom: 24 }} />
)}
{/* 加载状态 */}
{loading && !dataToDisplay && (
<div className="loading-container">
<Spin size="large" tip="加载数据中..." />
</div> </div>
)}
{/* 数据内容 */}
{dataToDisplay && (
<>
{/* 基本信息 */} {/* 基本信息 */}
<Card className="detail-card" style={{ marginBottom: 24 }}> <Card className="detail-card" style={{ marginBottom: 24 }}>
<Row gutter={[16, 16]}> <Row gutter={[16, 16]}>
<Col span={8}> <Col span={8}>
<Statistic <Statistic
title="当前价格" title="当前价格"
value={selectedFuture.currentPrice} value={dataToDisplay.currentPrice}
valueStyle={{ color: '#262626' }} valueStyle={{ color: '#262626' }}
/> />
</Col> </Col>
<Col span={8}> <Col span={8}>
<Statistic <Statistic
title="涨跌幅" title="涨跌幅"
value={Math.abs(selectedFuture.changePercent)} value={Math.abs(dataToDisplay.changePercent)}
suffix="%" suffix="%"
valueStyle={{ color: getChangeColor(selectedFuture.changePercent) }} valueStyle={{ color: getChangeColor(dataToDisplay.changePercent) }}
prefix={getChangeIcon(selectedFuture.changePercent)} prefix={getChangeIcon(dataToDisplay.changePercent)}
/> />
</Col> </Col>
<Col span={8}> <Col span={8}>
<Statistic <Statistic
title="胜率" title="胜率"
value={selectedFuture.winRate} value={dataToDisplay.winRate}
suffix="%" suffix="%"
valueStyle={{ color: selectedFuture.winRate > 60 ? '#52c41a' : selectedFuture.winRate > 40 ? '#faad14' : '#ff4d4f' }} valueStyle={{ color: dataToDisplay.winRate > 60 ? '#52c41a' : dataToDisplay.winRate > 40 ? '#faad14' : '#ff4d4f' }}
/> />
</Col> </Col>
<Col span={8}> <Col span={8}>
<Statistic <Statistic
title="ATR" title="ATR"
value={selectedFuture.atr} value={dataToDisplay.atr}
valueStyle={{ color: '#1890ff' }} valueStyle={{ color: '#1890ff' }}
/> />
</Col> </Col>
<Col span={8}> <Col span={8}>
<Statistic <Statistic
title="ADX" title="ADX"
value={selectedFuture.adx} value={dataToDisplay.adx}
valueStyle={{ color: '#1890ff' }} valueStyle={{ color: '#1890ff' }}
/> />
</Col> </Col>
<Col span={8}> <Col span={8}>
<Statistic <Statistic
title="趋势状态" title="趋势状态"
value={selectedFuture.adxStatus} value={dataToDisplay.adxStatus}
valueStyle={{ color: '#1890ff' }} valueStyle={{ color: '#1890ff' }}
/> />
</Col> </Col>
@ -253,7 +267,7 @@ const Detail = () => {
style={{ marginBottom: 24 }} style={{ marginBottom: 24 }}
> >
<Row gutter={[16, 16]}> <Row gutter={[16, 16]}>
{Object.entries(selectedFuture.trends).map(([period, trend]) => ( {Object.entries(dataToDisplay.trends).map(([period, trend]) => (
<Col span={6} key={period}> <Col span={6} key={period}>
<Card className="trend-card"> <Card className="trend-card">
<div className="trend-header"> <div className="trend-header">
@ -284,25 +298,25 @@ const Detail = () => {
<Col span={6}> <Col span={6}>
<div className="indicator-item"> <div className="indicator-item">
<div className="indicator-label">MACD</div> <div className="indicator-label">MACD</div>
<div className="indicator-value">{selectedFuture.indicators.macd}</div> <div className="indicator-value">{dataToDisplay.indicators.macd}</div>
</div> </div>
</Col> </Col>
<Col span={6}> <Col span={6}>
<div className="indicator-item"> <div className="indicator-item">
<div className="indicator-label">RSI</div> <div className="indicator-label">RSI</div>
<div className="indicator-value">{selectedFuture.indicators.rsi}</div> <div className="indicator-value">{dataToDisplay.indicators.rsi}</div>
</div> </div>
</Col> </Col>
<Col span={6}> <Col span={6}>
<div className="indicator-item"> <div className="indicator-item">
<div className="indicator-label">布林带</div> <div className="indicator-label">布林带</div>
<div className="indicator-value">{selectedFuture.indicators.bollinger}</div> <div className="indicator-value">{dataToDisplay.indicators.bollinger}</div>
</div> </div>
</Col> </Col>
<Col span={6}> <Col span={6}>
<div className="indicator-item"> <div className="indicator-item">
<div className="indicator-label">KDJ</div> <div className="indicator-label">KDJ</div>
<div className="indicator-value">{selectedFuture.indicators.kdj}</div> <div className="indicator-value">{dataToDisplay.indicators.kdj}</div>
</div> </div>
</Col> </Col>
</Row> </Row>
@ -318,21 +332,21 @@ const Detail = () => {
<Col span={8}> <Col span={8}>
<Statistic <Statistic
title="入场价" title="入场价"
value={selectedFuture.tradingAdvice.entry} value={dataToDisplay.tradingAdvice.entry}
valueStyle={{ color: '#1890ff' }} valueStyle={{ color: '#1890ff' }}
/> />
</Col> </Col>
<Col span={8}> <Col span={8}>
<Statistic <Statistic
title="止损价" title="止损价"
value={selectedFuture.tradingAdvice.stopLoss} value={dataToDisplay.tradingAdvice.stopLoss}
valueStyle={{ color: '#ff4d4f' }} valueStyle={{ color: '#ff4d4f' }}
/> />
</Col> </Col>
<Col span={8}> <Col span={8}>
<Statistic <Statistic
title="目标价" title="目标价"
value={selectedFuture.tradingAdvice.target} value={dataToDisplay.tradingAdvice.target}
valueStyle={{ color: '#52c41a' }} valueStyle={{ color: '#52c41a' }}
/> />
</Col> </Col>
@ -348,16 +362,16 @@ const Detail = () => {
<Col span={12}> <Col span={12}>
<div className="risk-item"> <div className="risk-item">
<div className="risk-label">风险等级</div> <div className="risk-label">风险等级</div>
<Tag color={selectedFuture.riskLevel === '高' ? 'red' : selectedFuture.riskLevel === '中等' ? 'orange' : 'green'}> <Tag color={dataToDisplay.riskLevel === '高' ? 'red' : dataToDisplay.riskLevel === '中等' ? 'orange' : 'green'}>
{selectedFuture.riskLevel} {dataToDisplay.riskLevel}
</Tag> </Tag>
</div> </div>
</Col> </Col>
<Col span={12}> <Col span={12}>
<div className="risk-item"> <div className="risk-item">
<div className="risk-label">波动率</div> <div className="risk-label">波动率</div>
<Tag color={selectedFuture.volatility === '高' ? 'red' : selectedFuture.volatility === '中等' ? 'orange' : 'green'}> <Tag color={dataToDisplay.volatility === '高' ? 'red' : dataToDisplay.volatility === '中等' ? 'orange' : 'green'}>
{selectedFuture.volatility} {dataToDisplay.volatility}
</Tag> </Tag>
</div> </div>
</Col> </Col>
@ -370,6 +384,18 @@ const Detail = () => {
style={{ marginTop: 16 }} style={{ marginTop: 16 }}
/> />
</Card> </Card>
</>
)}
{/* 无数据状态 */}
{!loading && !dataToDisplay && !error && (
<div className="error-container">
<Alert message="未找到品种数据" type="error" />
<Button type="primary" onClick={handleBack} style={{ marginTop: 16 }}>
返回主页
</Button>
</div>
)}
</div> </div>
); );
}; };

@ -83,10 +83,12 @@ const futuresSlice = createSlice({
.addCase(fetchFutureDetail.fulfilled, (state, action) => { .addCase(fetchFutureDetail.fulfilled, (state, action) => {
state.loading = false; state.loading = false;
state.selectedFuture = action.payload; state.selectedFuture = action.payload;
console.log('fetchFutureDetail fulfilled with:', action.payload);
}) })
.addCase(fetchFutureDetail.rejected, (state, action) => { .addCase(fetchFutureDetail.rejected, (state, action) => {
state.loading = false; state.loading = false;
state.error = action.error.message; state.error = action.error.message;
console.log('fetchFutureDetail rejected with error:', action.error.message);
}) })
// 处理fetchRiskAlerts // 处理fetchRiskAlerts

Loading…
Cancel
Save