返回 AiToEarn
finance.tsx
1 /*
2 * @Author: nevin
3 * @Date: 2025-02-10 22:20:15
4 * @LastEditTime: 2025-02-28 21:42:15
5 * @LastEditors: nevin
6 * @Description: 钱包页面
7 */
8 import {
9 VideoCameraOutlined,
10 WalletOutlined,
11 HistoryOutlined,
12 AccountBookOutlined,
13 QuestionCircleOutlined,
14 MoneyCollectOutlined,
15 SyncOutlined,
16 } from '@ant-design/icons';
17 import { Segmented, Card, Typography, Space, Row, Col, Tooltip, List, Tag, Button, message } from 'antd';
18 import { Outlet, useNavigate } from 'react-router-dom';
19 import styles from './finance.module.scss';
20 import { useState, useEffect } from 'react';
21 import { financeApi } from '@/api/finance';
22 import { taskApi } from '@/api/task';
23 import { UserTask, UserTaskStatus } from '@/api/types/task';
24 import { Pagination } from '@/api/types';
25 import { Task, TaskDataInfo } from 'commont/types/task';
26 import { PaginationMeta } from '@/api/platform';
27
28 const { Title, Text } = Typography;
29
30 interface TaskResponse {
31 list: UserTask<Task<TaskDataInfo>>[];
32 total: number;
33 pageSize: number;
34 pageNo: number;
35 }
36
37 export default function Page() {
38 const navigate = useNavigate();
39 const [balance, setBalance] = useState<number>(0);
40 const [pendingBalance, setPendingBalance] = useState<number>(0);
41 const [expectedIncomeList, setExpectedIncomeList] = useState<UserTask<Task<TaskDataInfo>>[]>([]);
42 const [loading, setLoading] = useState(false);
43 const [refreshing, setRefreshing] = useState(false);
44 const [pagination, setPagination] = useState({
45 current: 1,
46 pageSize: 10,
47 total: 0,
48 });
49
50 useEffect(() => {
51 getBalance();
52 getTotalAmountOfDoingTasks();
53 getExpectedIncomeList();
54 // 默认导航到提现记录界面
55 navigate('userWalletRecord', { replace: true });
56 }, [pagination.current]);
57
58 const getBalance = async () => {
59 try {
60 setRefreshing(true);
61 const res = await financeApi.getUserWalletInfo();
62 // console.log('getBalance','res',res);
63 setBalance(res.balance || 0);
64 } catch (error) {
65 console.error('获取余额失败:', error);
66 message.error('获取余额失败');
67 } finally {
68 setRefreshing(false);
69 }
70 };
71
72 const handleRefreshBalance = async () => {
73 message.loading({ content: '刷新中...', key: 'refreshBalance' });
74 await getBalance();
75 message.success({ content: '余额已更新', key: 'refreshBalance', duration: 2 });
76 };
77
78 const getTotalAmountOfDoingTasks = async () => {
79 try {
80 const res = await taskApi.getTotalAmountOfDoingTasks();
81 setPendingBalance(res || 0);
82 } catch (error) {
83 console.error('获取待提取余额失败:', error);
84 }
85 };
86
87 const getExpectedIncomeList = async () => {
88 try {
89 setLoading(true);
90 const params = {
91 pageSize: pagination.pageSize,
92 pageNo: pagination.current,
93 status: UserTaskStatus.APPROVED
94 };
95 const res = await taskApi.getMineTaskList(params);
96 console.log('getExpectedIncomeList','res',res);
97 setExpectedIncomeList(res.items || []);
98 setPagination(prev => ({
99 ...prev,
100 ...res.meta
101 }));
102 } catch (error) {
103 console.error('获取预计收入列表失败:', error);
104 } finally {
105 setLoading(false);
106 }
107 };
108
109 return (
110 <div className={styles.finance}>
111 <div className={styles.header}>
112 <Card className={styles.balanceCard} bordered={false}>
113 <Row align="middle" justify="space-between">
114 <Col>
115 <Space direction="vertical" size="small">
116 <div style={{ display: 'flex', alignItems: 'center' }}>
117 <Text type="secondary" className={styles.balanceLabel}>
118 账户余额
119 </Text>
120 <Button
121 type="text"
122 size="small"
123 icon={<SyncOutlined spin={refreshing} />}
124 onClick={handleRefreshBalance}
125 style={{ marginLeft: 4, padding: '0 4px', color: '#ccc' }}
126 />
127 </div>
128 <div className="flex items-center">
129 <Title level={2} className={styles.balanceAmount}>
130 ¥{balance.toFixed(2)}
131 </Title>
132 <div className="flex items-center ml-4"
133 onClick={() => {
134 // navigate('expectedIncome');
135 }}>
136 {/* <Text type="secondary" className="text-sm" style={{ color: '#ccc' }}>
137 预计收益: ¥{pendingBalance.toFixed(2) }
138 </Text> */}
139 <Tooltip
140 title="提现打款预计3-7个工作日到账"
141 placement="top"
142 >
143 <QuestionCircleOutlined className="ml-1 text-gray-400 cursor-help" />
144 </Tooltip>
145 </div>
146 </div>
147 </Space>
148 </Col>
149 <Col>
150 <WalletOutlined className={styles.walletIcon} />
151 </Col>
152 </Row>
153 </Card>
154 </div>
155 <div className={styles.content}>
156 <div className={styles.sidebar}>
157 <Segmented
158 vertical
159 size="large"
160 options={[
161 {
162 label: '提现记录',
163 value: 'userWalletRecord',
164 icon: <HistoryOutlined />,
165 },
166 {
167 label: '钱包账户',
168 value: 'userWalletAccount',
169 icon: <AccountBookOutlined />,
170 },
171 // {
172 // label: '预计收入',
173 // value: 'expectedIncome',
174 // icon: <MoneyCollectOutlined />,
175 // },
176 ]}
177 onChange={(value) => {
178 navigate(value);
179 }}
180 className={styles.segmented}
181 />
182 </div>
183 <div className={styles.outlet}>
184 <Outlet />
185 </div>
186 </div>
187
188 </div>
189 );
190 }
191
191 lines Plain Text