blob: ca789c59043706b0ce85c566e907ea9501bb5e75 [file] [log] [blame]
崔向南464e19d2025-06-05 17:46:27 +08001import React, { useState, useEffect } from 'react';
2import { Table, Button, message, Space, Modal } from 'antd';
3import axios from 'axios'; // 新增 axios 导入
4import { useNavigate } from 'umi';
5
6import { getBountyList } from '@/services/bounty/bounty';
7import BountyPublish from './BountyPublish';
8import BountyReply from './BountyReply';
9const BountyList: React.FC = () => {
10 const [dataSource, setDataSource] = useState<API.Bounty[]>([]);
11 const [loading, setLoading] = useState(false);
12 const [publishVisible, setPublishVisible] = useState(false);
13 const [replyVisible, setReplyVisible] = useState(false);
14 const [selectedId, setSelectedId] = useState<number | null>(null);
15
16 const navigate = useNavigate();
17
18 // 加载悬赏列表(修改请求方式)
19
20 const loadBountyList = async () => {
21 try {
22 setLoading(true);
23 const res = await getBountyList();
24
25 // 添加详细日志输出
26 console.log('接口原始响应:', res);
27
28 // 修改数据处理逻辑以适配实际数据结构
29 if (res && Array.isArray(res)) {
30 // 当接口直接返回数组时
31 setDataSource(res);
32 } else if (res && res.code === 200) {
33 // 当接口返回标准分页结构时
34 setDataSource(res.data.records || res.data || []);
35 } else {
36 throw new Error('接口返回异常结构');
37 }
38 } catch (err) {
39 console.error('加载数据异常:', err);
40 console.error('完整错误:', err);
41
42 // 添加网络错误处理
43 // @ts-ignore
44 if (err?.response?.status === 401) {
45 message.error('认证失效,请重新登录');
46 navigate('/login');
47 } else {
48 message.error('加载悬赏列表失败');
49 }
50 } finally {
51 setLoading(false);
52 }
53 };
54
55 useEffect(() => {
56 loadBountyList();
57 }, []);
58
59 // ✅ 发布成功回调(普通函数,无需useEffect)
60 const handlePublishSuccess = () => {
61 setPublishVisible(false);
62 loadBountyList(); // 重新加载数据
63 message.success('悬赏发布成功');
64 };
65
66 // ✅ 回复成功回调(普通函数,无需useEffect)
67 const handleReplySuccess = () => {
68 setReplyVisible(false);
69 loadBountyList(); // 重新加载数据
70 message.success('回复提交成功');
71 };
72
73
74 // 跳转详情页
75 const goDetail = (id: number) => {
76 navigate(`/bounty/detail/${id}`);
77 };
78
79 // 表格列配置
80 const columns = [
81 {
82 title: '标题',
83 dataIndex: 'title',
84 width: 200,
85 ellipsis: true,
86 },
87 {
88 title: '发布者ID',
89 dataIndex: 'creator_id', // ✅ 新增列
90 width: 100,
91 align: 'center' as const,
92 },
93 {
94 title: '奖励',
95 dataIndex: 'reward',
96 width: 100,
97 align: 'center' as const,
98 },
99 {
100 title: '状态',
101 dataIndex: 'status',
102 width: 100,
103 render: (status: number) => (
104 status === 0 ? '未回复' : status === 1 ? '已回复' : '已关闭'
105 )
106 },
107 {
108 title: '操作',
109 width: 160,
110 render: (value: unknown, record: API.Bounty) => (
111 <Space>
112 <Button
113 type="link"
114 onClick={() => navigate(`/bounty/detail/${record.id}`)}
115 >
116 查看详情
117 </Button>
118 <Button
119 type="link"
120 onClick={() => {
121 setSelectedId(record.id);
122 setReplyVisible(true);
123 }}
124 >
125 回复悬赏
126 </Button>
127 </Space>
128 )
129 }
130 ];
131
132 return (
133 <div className="page-container">
134 {/* 顶部操作区 */}
135 <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}>
136 <h2>悬赏列表</h2>
137 {/* 发布按钮 */}
138 <Button
139 type="primary"
140 onClick={() => setPublishVisible(true)}
141 >
142 发布悬赏
143 </Button>
144 </div>
145
146 {/* 悬赏列表 */}
147 <Table
148 dataSource={dataSource}
149 columns={columns}
150 rowKey="id"
151 pagination={{ pageSize: 10 }}
152 loading={loading}
153 />
154
155 {/* 发布悬赏模态框 */}
156 <Modal
157 title="发布新悬赏"
158 open={publishVisible}
159 onCancel={() => setPublishVisible(false)}
160 footer={null}
161 >
162 <BountyPublish onSuccess={handlePublishSuccess} />
163 </Modal>
164
165 {/* 回复悬赏模态框 */}
166 <Modal
167 title="回复悬赏"
168 open={replyVisible}
169 onCancel={() => setReplyVisible(false)}
170 footer={null}
171 >
172 {selectedId && (
173 <BountyReply
174 bountyId={selectedId}
175 onSuccess={handleReplySuccess}
176 />
177 )}
178 </Modal>
179 </div>
180 );
181};
182
183export default BountyList;