blob: 231415cc136505eaf521612a457776fe83473d06 [file] [log] [blame]
BirdNETMb0f71532025-05-26 17:37:33 +08001import { ExclamationCircleOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons';
2import { Button, message, Modal, Switch } from 'antd';
3import React, { useRef, useState, useEffect } from 'react';
4import { FormattedMessage, useIntl } from 'umi';
5import { FooterToolbar, PageContainer } from '@ant-design/pro-layout';
6import type { ActionType, ProColumns } from '@ant-design/pro-table';
7import ProTable from '@ant-design/pro-table';
8import type { FormInstance } from 'antd';
9import { getRewardList, removeReward, updateReward, addReward } from './service';
10import UpdateForm from './components/UpdateForm';
11import { getDictValueEnum } from '@/services/system/dict';
12import DictTag from '@/components/DictTag';
13import { useAccess } from 'umi';
14import { RewardItem, RewardListParams } from './data';
15
16/**
17 * 删除节点
18 *
19 * @param selectedRows
20 */
21const handleRemove = async (selectedRows: RewardItem[]) => {
22 const hide = message.loading('正在删除');
23 if (!selectedRows) return true;
24 try {
25 await removeReward(selectedRows.map((row) => row.rewardId).join(','));
26 hide();
27 message.success('删除成功');
28 return true;
29 } catch (error) {
30 hide();
31 message.error('删除失败,请重试');
32 return false;
33 }
34};
35
36const handleUpdate = async (fields: RewardItem) => {
37 const hide = message.loading('正在更新');
38 try {
39 const resp = await updateReward(fields);
40 hide();
41 if (resp.code === 200) {
42 message.success('更新成功');
43 } else {
44 message.error(resp.msg);
45 }
46 return true;
47 } catch (error) {
48 hide();
49 message.error('配置失败请重试!');
50 return false;
51 }
52};
53
54const handleAdd = async (fields: RewardItem) => {
55 const hide = message.loading('正在添加');
56 try {
57 const resp = await addReward(fields);
58 hide();
59 if (resp.code === 200) {
60 message.success('添加成功');
61 } else {
62 message.error(resp.msg);
63 }
64 return true;
65 } catch (error) {
66 hide();
67 message.error('配置失败请重试!');
68 return false;
69 }
70};
71
72const RewardTableList: React.FC = () => {
73 const formTableRef = useRef<FormInstance>();
74
75 const [modalVisible, setModalVisible] = useState<boolean>(false);
76 const [readOnly, setReadOnly] = useState<boolean>(false);
77
78 const actionRef = useRef<ActionType>();
79 const [currentRow, setCurrentRow] = useState<RewardItem>();
80 const [selectedRows, setSelectedRows] = useState<RewardItem[]>([]);
81
82 const [statusOptions, setStatusOptions] = useState<any>([]);
83
84 const access = useAccess();
85
86 /** 国际化配置 */
87 const intl = useIntl();
88
89 useEffect(() => {
90 getDictValueEnum('reward_status').then((data) => {
91 setStatusOptions(data);
92 });
93 }, []);
94
95 const columns: ProColumns<RewardItem>[] = [
96 {
97 title: '悬赏ID',
98 dataIndex: 'rewardId',
99 valueType: 'text',
100 hideInSearch: true,
101 },
102 {
103 title: '悬赏标题',
104 dataIndex: 'title',
105 valueType: 'text',
106 },
107 {
108 title: '悬赏金额',
109 dataIndex: 'amount',
110 valueType: 'money',
111 hideInSearch: true,
112 },
113 // {
114 // title: '悬赏状态',
115 // dataIndex: 'status',
116 // valueType: 'select',
117 // valueEnum: statusOptions,
118 // render: (_, record) => {
119 // return (<DictTag enums={statusOptions} value={record.status} />);
120 // },
121 // },
122 {
123 title: '发布时间',
124 dataIndex: 'createTime',
125 valueType: 'dateRange',
126 render: (_, record) => {
127 return (<span>{record.createTime?.toString()}</span>);
128 },
129 search: {
130 transform: (value) => {
131 return {
132 'params[beginTime]': value[0],
133 'params[endTime]': value[1],
134 };
135 },
136 },
137 },
138 {
139 title: '备注',
140 dataIndex: 'remark',
141 valueType: 'text',
142 hideInSearch: true,
143 },
144 {
145 title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="操作" />,
146 dataIndex: 'option',
147 width: '220px',
148 valueType: 'option',
149 render: (_, record) => [
150 <Button
151 type="link"
152 size="small"
153 key="view"
154 onClick={() => {
155 setModalVisible(true);
156 setCurrentRow(record);
157 // 设置只读模式
158 setReadOnly(true);
159 }}
160 >
161 查看
162 </Button>,
163 <Button
164 type="link"
165 size="small"
166 key="edit"
167 hidden={!access.hasPerms('reward:reward:edit')}
168 onClick={() => {
169 setModalVisible(true);
170 setCurrentRow(record);
171 setReadOnly(false);
172 }}
173 >
174 编辑
175 </Button>,
176 <Button
177 type="link"
178 size="small"
179 danger
180 key="batchRemove"
181 hidden={!access.hasPerms('reward:reward:remove')}
182 onClick={async () => {
183 Modal.confirm({
184 title: '删除',
185 content: '确定删除该项吗?',
186 okText: '确认',
187 cancelText: '取消',
188 onOk: async () => {
189 const success = await handleRemove([record]);
190 if (success) {
191 if (actionRef.current) {
192 actionRef.current.reload();
193 }
194 }
195 },
196 });
197 }}
198 >
199 删除
200 </Button>,
201 ],
202 },
203 ];
204
205 return (
206 <PageContainer>
207 <div style={{ width: '100%', float: 'right' }}>
208 <ProTable<RewardItem>
209 headerTitle={intl.formatMessage({
210 id: 'pages.searchTable.title',
211 defaultMessage: '信息',
212 })}
213 actionRef={actionRef}
214 formRef={formTableRef}
215 rowKey="rewardId"
216 key="rewardList"
217 search={{
218 labelWidth: 120,
219 }}
220 toolBarRender={() => [
221 <Button
222 type="primary"
223 key="add"
224 hidden={!access.hasPerms('reward:reward:add')}
225 onClick={async () => {
226 setCurrentRow(undefined);
227 setModalVisible(true);
228 }}
229 >
230 <PlusOutlined /> <FormattedMessage id="pages.searchTable.new" defaultMessage="新建" />
231 </Button>,
232 <Button
233 type="primary"
234 key="remove"
235 danger
236 hidden={selectedRows?.length === 0 || !access.hasPerms('reward:reward:remove')}
237 onClick={async () => {
238 Modal.confirm({
239 title: '是否确认删除所选数据项?',
240 icon: <ExclamationCircleOutlined />,
241 content: '请谨慎操作',
242 async onOk() {
243 const success = await handleRemove(selectedRows);
244 if (success) {
245 setSelectedRows([]);
246 actionRef.current?.reloadAndRest?.();
247 }
248 },
249 onCancel() { },
250 });
251 }}
252 >
253 <DeleteOutlined />
254 <FormattedMessage id="pages.searchTable.delete" defaultMessage="删除" />
255 </Button>,
256 ]}
257 request={(params) =>
258 getRewardList({ ...params } as RewardListParams).then((res) => {
259 return {
260 data: res.rows,
261 total: res.total,
262 success: true,
263 };
264 })
265 }
266 columns={columns}
267 rowSelection={{
268 onChange: (_, selectedRows) => {
269 setSelectedRows(selectedRows);
270 },
271 }}
272 />
273 </div>
274 {selectedRows?.length > 0 && (
275 <FooterToolbar
276 extra={
277 <div>
278 <FormattedMessage id="pages.searchTable.chosen" defaultMessage="已选择" />
279 <a style={{ fontWeight: 600 }}>{selectedRows.length}</a>
280 <FormattedMessage id="pages.searchTable.item" defaultMessage="项" />
281 </div>
282 }
283 >
284 <Button
285 key="remove"
286 danger
287 hidden={!access.hasPerms('reward:reward:remove')}
288 onClick={async () => {
289 Modal.confirm({
290 title: '删除',
291 content: '确定删除该项吗?',
292 okText: '确认',
293 cancelText: '取消',
294 onOk: async () => {
295 const success = await handleRemove(selectedRows);
296 if (success) {
297 setSelectedRows([]);
298 actionRef.current?.reloadAndRest?.();
299 }
300 },
301 });
302 }}
303 >
304 <FormattedMessage id="pages.searchTable.batchDeletion" defaultMessage="批量删除" />
305 </Button>
306 </FooterToolbar>
307 )}
308 <UpdateForm
309 readOnly={readOnly}
310 onSubmit={async (values) => {
311 let success = false;
312 if (values.rewardId) {
313 success = await handleUpdate({ ...values } as RewardItem);
314 } else {
315 success = await handleAdd({ ...values } as RewardItem);
316 }
317 if (success) {
318 setModalVisible(false);
319 setCurrentRow(undefined);
320 if (actionRef.current) {
321 actionRef.current.reload();
322 }
323 }
324 }}
325 onCancel={() => {
326 setModalVisible(false);
327 setCurrentRow(undefined);
328 setReadOnly(false);
329 }}
330 open={modalVisible}
331 values={currentRow || {}}
332 statusOptions={statusOptions}
333 />
334 </PageContainer>
335 );
336};
337
338export default RewardTableList;