fix: 卡片页面微调,增加排序

master
Lxy 3 months ago
parent 361daff9cc
commit ab9f722f78

@ -8,20 +8,27 @@ import './App.css';
function App() { function App() {
const [currentMenu, setCurrentMenu] = useState('dashboard'); const [currentMenu, setCurrentMenu] = useState('dashboard');
const [selectedFuture, setSelectedFuture] = useState({ code: 'MA', name: '甲醇' });
//
const handleViewDetail = (code, name) => {
setSelectedFuture({ code, name });
setCurrentMenu('detail');
};
// //
const renderCurrentPage = () => { const renderCurrentPage = () => {
switch (currentMenu) { switch (currentMenu) {
case 'dashboard': case 'dashboard':
return <Dashboard />; return <Dashboard onViewDetail={handleViewDetail} />;
case 'detail': case 'detail':
return <Detail />; return <Detail selectedFuture={selectedFuture} />;
case 'risk-control': case 'risk-control':
return <RiskControl />; return <RiskControl />;
case 'config': case 'config':
return <Config />; return <Config />;
default: default:
return <Dashboard />; return <Dashboard onViewDetail={handleViewDetail} />;
} }
}; };

@ -9,13 +9,14 @@ const { Search } = Input;
const { Option } = Select; const { Option } = Select;
const { Column } = Table; const { Column } = Table;
const Dashboard = () => { const Dashboard = ({ onViewDetail }) => {
const [futuresData, setFuturesData] = useState(allFuturesData); const [futuresData, setFuturesData] = useState(allFuturesData);
const [filteredData, setFilteredData] = useState(allFuturesData); const [filteredData, setFilteredData] = useState(allFuturesData);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [viewMode, setViewMode] = useState('card'); // card or list const [viewMode, setViewMode] = useState('card'); // card or list
const [filterType, setFilterType] = useState(''); const [filterType, setFilterType] = useState('');
const [filterKeyword, setFilterKeyword] = useState(''); const [filterKeyword, setFilterKeyword] = useState('');
const [sortRule, setSortRule] = useState('original'); // original, hot, bullish, bearish, neutral
// //
const handleRefresh = () => { const handleRefresh = () => {
@ -32,10 +33,11 @@ const Dashboard = () => {
}, 1000); }, 1000);
}; };
// //
useEffect(() => { useEffect(() => {
let result = futuresData; let result = futuresData;
//
if (filterKeyword) { if (filterKeyword) {
const keyword = filterKeyword.toLowerCase(); const keyword = filterKeyword.toLowerCase();
result = result.filter(item => result = result.filter(item =>
@ -48,8 +50,47 @@ const Dashboard = () => {
result = result.filter(item => item.type === filterType); result = result.filter(item => item.type === filterType);
} }
//
switch (sortRule) {
case 'hot':
//
result.sort((a, b) => Math.abs(b.changePercent) - Math.abs(a.changePercent));
break;
case 'bullish':
//
result.sort((a, b) => {
//
const aBullishCount = Object.values(a.trends).filter(trend => trend.direction === '看多').length;
const bBullishCount = Object.values(b.trends).filter(trend => trend.direction === '看多').length;
return bBullishCount - aBullishCount;
});
break;
case 'bearish':
//
result.sort((a, b) => {
//
const aBearishCount = Object.values(a.trends).filter(trend => trend.direction === '看空').length;
const bBearishCount = Object.values(b.trends).filter(trend => trend.direction === '看空').length;
return bBearishCount - aBearishCount;
});
break;
case 'neutral':
//
result.sort((a, b) => {
//
const aNeutralCount = Object.values(a.trends).filter(trend => trend.status.includes('震荡')).length;
const bNeutralCount = Object.values(b.trends).filter(trend => trend.status.includes('震荡')).length;
return bNeutralCount - aNeutralCount;
});
break;
case 'original':
default:
//
break;
}
setFilteredData(result); setFilteredData(result);
}, [futuresData, filterKeyword, filterType]); }, [futuresData, filterKeyword, filterType, sortRule]);
// //
const typeOptions = Array.from(new Set(allFuturesData.map(item => item.type))).map(type => ( const typeOptions = Array.from(new Set(allFuturesData.map(item => item.type))).map(type => (
@ -152,10 +193,18 @@ const Dashboard = () => {
{/* AI分析 */} {/* AI分析 */}
<Col span={24}> <Col span={24}>
<div style={{ fontSize: '12px', fontWeight: 'bold', marginBottom: 4 }}>AI分析:</div> <div style={{ fontSize: '12px', fontWeight: 'bold', marginBottom: 4 }}>AI分析:</div>
<div style={{ fontSize: '11px', color: '#8c8c8c', lineHeight: 1.4 }}> <div style={{ fontSize: '11px', color: '#8c8c8c', lineHeight: 1.4, marginBottom: 8 }}>
MACD: {item.aiAnalysis.macd}<br /> MACD: {item.aiAnalysis.macd}<br />
{item.aiAnalysis.rsi} {item.aiAnalysis.rsi}
</div> </div>
<Button
type="primary"
size="small"
block
onClick={() => onViewDetail && onViewDetail(item.code, item.name)}
>
查看详细分析
</Button>
</Col> </Col>
</Row> </Row>
</Card> </Card>
@ -194,7 +243,7 @@ const Dashboard = () => {
style={{ width: '100%' }} style={{ width: '100%' }}
/> />
</Col> </Col>
<Col span={8}> <Col span={16}>
<Select <Select
placeholder="按品种类型筛选" placeholder="按品种类型筛选"
style={{ width: '100%' }} style={{ width: '100%' }}
@ -208,7 +257,51 @@ const Dashboard = () => {
</Row> </Row>
{/* 品种概览区 */} {/* 品种概览区 */}
<Card title="品种概览" style={{ marginBottom: 24 }}> <Card
title={
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span>品种概览</span>
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
<Button
type={sortRule === 'original' ? 'primary' : 'default'}
size="small"
onClick={() => setSortRule('original')}
>
原始
</Button>
<Button
type={sortRule === 'hot' ? 'primary' : 'default'}
size="small"
onClick={() => setSortRule('hot')}
>
热点
</Button>
<Button
type={sortRule === 'bullish' ? 'primary' : 'default'}
size="small"
onClick={() => setSortRule('bullish')}
>
看多
</Button>
<Button
type={sortRule === 'bearish' ? 'primary' : 'default'}
size="small"
onClick={() => setSortRule('bearish')}
>
看空
</Button>
<Button
type={sortRule === 'neutral' ? 'primary' : 'default'}
size="small"
onClick={() => setSortRule('neutral')}
>
观望
</Button>
</div>
</div>
}
style={{ marginBottom: 24 }}
>
<Spin spinning={loading}> <Spin spinning={loading}>
{viewMode === 'card' ? ( {viewMode === 'card' ? (
<Row gutter={[16, 16]}> <Row gutter={[16, 16]}>
@ -219,9 +312,20 @@ const Dashboard = () => {
))} ))}
</Row> </Row>
) : ( ) : (
<Table dataSource={filteredData} rowKey="code" pagination={{ pageSize: 10 }}> <Table
<Column title="品种" dataIndex="name" key="name" render={(text, record) => `${text} (${record.code})`} /> dataSource={filteredData}
rowKey="code"
pagination={{ pageSize: 10 }}
onRow={(record) => ({
onClick: () => onViewDetail && onViewDetail(record.code, record.name),
style: { cursor: 'pointer' }
})}
>
<Column title="品种" dataIndex="name" key="name" render={(text, record) => `${text}-${record.code}2603`} />
<Column title="当前价格" dataIndex="currentPrice" key="currentPrice" /> <Column title="当前价格" dataIndex="currentPrice" key="currentPrice" />
<Column title="支撑" dataIndex="support" key="support" />
<Column title="压力" dataIndex="resistance" key="resistance" />
<Column title="胜率" dataIndex="winRate" key="winRate" render={(text) => `${text}%`} />
<Column <Column
title="涨跌幅" title="涨跌幅"
dataIndex="changePercent" dataIndex="changePercent"
@ -232,10 +336,9 @@ const Dashboard = () => {
</span> </span>
)} )}
/> />
<Column title="胜率" dataIndex="winRate" key="winRate" render={(text) => `${text}%`} />
<Column title="ATR" dataIndex="atr" key="atr" /> <Column title="ATR" dataIndex="atr" key="atr" />
<Column title="ADX" dataIndex="adx" key="adx" /> <Column title="ADX" dataIndex="adx" key="adx" />
<Column title="趋势状态" dataIndex="adxStatus" key="adxStatus" /> <Column title="整体预判" dataIndex="overallView" key="overallView" />
</Table> </Table>
)} )}
</Spin> </Spin>

@ -12,13 +12,21 @@ const { Option } = Select;
const { TabPane } = Tabs; const { TabPane } = Tabs;
const { Column } = Table; const { Column } = Table;
const Detail = () => { const Detail = ({ selectedFuture: propsSelectedFuture }) => {
const [selectedFuture, setSelectedFuture] = useState('MA'); const [selectedFuture, setSelectedFuture] = useState(propsSelectedFuture?.code || 'MA');
const [futureData, setFutureData] = useState(generateFutureData('MA', '甲醇')); const [futureData, setFutureData] = useState(generateFutureData(propsSelectedFuture?.code || 'MA', propsSelectedFuture?.name || '甲醇'));
const [timePeriod, setTimePeriod] = useState('1DAY'); const [timePeriod, setTimePeriod] = useState('1DAY');
const [chart, setChart] = useState(null); const [chart, setChart] = useState(null);
const chartRef = useRef(null); const chartRef = useRef(null);
//
useEffect(() => {
if (propsSelectedFuture) {
setSelectedFuture(propsSelectedFuture.code);
setFutureData(generateFutureData(propsSelectedFuture.code, propsSelectedFuture.name));
}
}, [propsSelectedFuture]);
// //
const futuresList = [ const futuresList = [
{ code: 'MA', name: '甲醇' }, { code: 'MA', name: '甲醇' },

Loading…
Cancel
Save