|
|
|
|
@ -1,8 +1,8 @@
|
|
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
|
|
|
import { Card, Row, Col, Button, Select, Tag, message, Spin, Input, Modal, Popconfirm } from 'antd';
|
|
|
|
|
import { ReloadOutlined, ArrowUpOutlined, ArrowDownOutlined, StarOutlined, DeleteOutlined, PlusOutlined, MoreOutlined } from '@ant-design/icons';
|
|
|
|
|
import { fetchFuturesOverview, toggleWatchlist, createWatchlist, selectWatchlist, deleteWatchlist } from '../../store/futuresSlice';
|
|
|
|
|
import { Card, Row, Col, Button, Select, Tag, message, Spin } from 'antd';
|
|
|
|
|
import { ReloadOutlined, ArrowUpOutlined, ArrowDownOutlined, StarOutlined, DeleteOutlined } from '@ant-design/icons';
|
|
|
|
|
import { fetchFuturesOverview, toggleWatchlist } from '../../store/futuresSlice';
|
|
|
|
|
import { useNavigate } from 'react-router-dom';
|
|
|
|
|
import './Watchlist.css';
|
|
|
|
|
|
|
|
|
|
@ -11,10 +11,8 @@ const { Option } = Select;
|
|
|
|
|
const Watchlist = () => {
|
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
const { overview, watchlists, currentWatchlist, loading } = useSelector(state => state.futures);
|
|
|
|
|
const { overview, watchlist, loading } = useSelector(state => state.futures);
|
|
|
|
|
const [filterType, setFilterType] = useState('all');
|
|
|
|
|
const [showCreateModal, setShowCreateModal] = useState(false);
|
|
|
|
|
const [newWatchlistName, setNewWatchlistName] = useState('');
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
dispatch(fetchFuturesOverview());
|
|
|
|
|
@ -29,32 +27,11 @@ const Watchlist = () => {
|
|
|
|
|
navigate(`/detail/${future.code}`);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleToggleWatchlist = (future, e) => {
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
dispatch(toggleWatchlist({ code: future.code, watchlistId: currentWatchlist }));
|
|
|
|
|
const handleToggleWatchlist = (future) => {
|
|
|
|
|
dispatch(toggleWatchlist(future.code));
|
|
|
|
|
message.success(future.isInWatchlist ? '已从自选移除' : '已添加到自选');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleCreateWatchlist = () => {
|
|
|
|
|
if (newWatchlistName.trim()) {
|
|
|
|
|
dispatch(createWatchlist({ name: newWatchlistName.trim() }));
|
|
|
|
|
message.success('新自选组合创建成功');
|
|
|
|
|
setShowCreateModal(false);
|
|
|
|
|
setNewWatchlistName('');
|
|
|
|
|
} else {
|
|
|
|
|
message.error('请输入自选组合名称');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleSelectWatchlist = (watchlistId) => {
|
|
|
|
|
dispatch(selectWatchlist(watchlistId));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDeleteWatchlist = (watchlistId) => {
|
|
|
|
|
dispatch(deleteWatchlist(watchlistId));
|
|
|
|
|
message.success('自选组合删除成功');
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getChangeColor = (changePercent) => {
|
|
|
|
|
return changePercent >= 0 ? '#52c41a' : '#ff4d4f';
|
|
|
|
|
};
|
|
|
|
|
@ -70,9 +47,7 @@ const Watchlist = () => {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getWatchlistData = () => {
|
|
|
|
|
const currentWl = watchlists.find(wl => wl.id === currentWatchlist);
|
|
|
|
|
if (!currentWl) return [];
|
|
|
|
|
return overview.filter(item => currentWl.codes.includes(item.code));
|
|
|
|
|
return overview.filter(item => watchlist.includes(item.code));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (loading && overview.length === 0) {
|
|
|
|
|
@ -89,31 +64,8 @@ const Watchlist = () => {
|
|
|
|
|
<div className="watchlist">
|
|
|
|
|
{/* 页面头部 */}
|
|
|
|
|
<div className="watchlist-header">
|
|
|
|
|
<div className="watchlist-header-left">
|
|
|
|
|
<h2>自选合约</h2>
|
|
|
|
|
<div className="watchlist-selector">
|
|
|
|
|
<Select
|
|
|
|
|
value={currentWatchlist}
|
|
|
|
|
onChange={handleSelectWatchlist}
|
|
|
|
|
style={{ width: 200, marginLeft: 16 }}
|
|
|
|
|
>
|
|
|
|
|
{watchlists.map(watchlist => (
|
|
|
|
|
<Option key={watchlist.id} value={watchlist.id}>
|
|
|
|
|
{watchlist.name}
|
|
|
|
|
</Option>
|
|
|
|
|
))}
|
|
|
|
|
</Select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="watchlist-header-actions">
|
|
|
|
|
<Button
|
|
|
|
|
type="default"
|
|
|
|
|
icon={<PlusOutlined />}
|
|
|
|
|
onClick={() => setShowCreateModal(true)}
|
|
|
|
|
style={{ marginRight: 16 }}
|
|
|
|
|
>
|
|
|
|
|
新建自选组合
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
type="primary"
|
|
|
|
|
icon={<ReloadOutlined />}
|
|
|
|
|
@ -245,28 +197,6 @@ const Watchlist = () => {
|
|
|
|
|
</Row>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/* 创建新自选组合模态框 */}
|
|
|
|
|
<Modal
|
|
|
|
|
title="创建新自选组合"
|
|
|
|
|
open={showCreateModal}
|
|
|
|
|
onCancel={() => setShowCreateModal(false)}
|
|
|
|
|
footer={[
|
|
|
|
|
<Button key="cancel" onClick={() => setShowCreateModal(false)}>
|
|
|
|
|
取消
|
|
|
|
|
</Button>,
|
|
|
|
|
<Button key="create" type="primary" onClick={handleCreateWatchlist}>
|
|
|
|
|
创建
|
|
|
|
|
</Button>
|
|
|
|
|
]}
|
|
|
|
|
>
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="请输入自选组合名称"
|
|
|
|
|
value={newWatchlistName}
|
|
|
|
|
onChange={(e) => setNewWatchlistName(e.target.value)}
|
|
|
|
|
style={{ marginBottom: 16 }}
|
|
|
|
|
/>
|
|
|
|
|
</Modal>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|