blob: 6b945240fccdfc5236d2d061a251a04d3c564f3e [file] [log] [blame]
ybtda5978b2025-05-31 15:58:05 +08001import React, { useState } from "react";
2import {
3 Typography,
4 Tabs,
5 Form,
6 Input,
7 Upload,
8 Button,
9 Select,
10 DatePicker,
11 InputNumber,
12 Radio,
13 Checkbox,
14 Collapse,
15 Alert,
16 Divider,
17 Space,
18 message,
19} from "antd";
20import {
21 UploadOutlined,
22 InboxOutlined,
23 InfoCircleOutlined,
24} from "@ant-design/icons";
ybtff3665a2025-06-09 23:53:39 +080025import { uploadTorrent } from "../../../api/torrents";
26import { useAuth } from "../../auth/contexts/AuthContext";
ybtda5978b2025-05-31 15:58:05 +080027
28const { Title, Paragraph, Text } = Typography;
29const { TabPane } = Tabs;
30const { Option } = Select;
31const { TextArea } = Input;
32const { Panel } = Collapse;
33const { Dragger } = Upload;
34
35// 通用的上传组件配置
36const uploadProps = {
37 name: "torrent",
38 multiple: false,
ybtda5978b2025-05-31 15:58:05 +080039 accept: ".torrent",
40 maxCount: 1,
ybtda5978b2025-05-31 15:58:05 +080041 beforeUpload(file) {
42 const isTorrent = file.type === "application/x-bittorrent" || file.name.endsWith(".torrent");
43 if (!isTorrent) {
44 message.error("您只能上传 .torrent 文件!");
ybtff3665a2025-06-09 23:53:39 +080045 return Upload.LIST_IGNORE;
ybtda5978b2025-05-31 15:58:05 +080046 }
ybtff3665a2025-06-09 23:53:39 +080047 // 阻止自动上传,我们将在表单提交时手动处理
48 return false;
ybtda5978b2025-05-31 15:58:05 +080049 },
50};
51
52// 注意事项内容
53const NoticeContent = () => (
54 <div className="space-y-4">
55 <Alert
56 message="请仔细阅读以下注意事项"
57 description="上传种子前,请确保您了解并同意以下规则,否则您的种子可能会被删除或您的账号可能会被处罚。"
58 type="info"
59 showIcon
60 />
61
62 <Collapse defaultActiveKey={["1"]}>
63 <Panel header="一般规则" key="1">
64 <ul className="list-disc pl-8 space-y-2">
65 <li>您上传的资源必须是合法的,不得上传侵犯版权的内容。</li>
66 <li>禁止上传含有恶意代码的文件,所有上传内容会经过安全检查。</li>
67 <li>资源标题必须清晰描述内容,不得使用误导性标题。</li>
68 <li>请确保您提供的信息准确完整,包括分类、标签、简介等。</li>
69 <li>如发现重复资源,管理员有权合并或删除。</li>
70 <li>新用户需要达到一定等级后才能上传资源,具体请参考用户等级规则。</li>
71 </ul>
72 </Panel>
73 <Panel header="做种要求" key="2">
74 <ul className="list-disc pl-8 space-y-2">
75 <li>上传者必须保证做种至少 7 天,或直到至少有 3 个其他用户完成下载。</li>
76 <li>对于大型资源({'>'}20GB),请确保您有足够的上传带宽。</li>
77 <li>对于稀有资源,请尽可能长期做种,这将获得额外的积分奖励。</li>
78 <li>故意停止做种可能导致警告或账号处罚。</li>
79 </ul>
80 </Panel>
81 <Panel header="奖励政策" key="3">
82 <ul className="list-disc pl-8 space-y-2">
83 <li>首发资源将获得额外的积分奖励。</li>
84 <li>高质量的资源(高分辨率、完整音轨等)将获得质量加成。</li>
85 <li>稀有、珍贵的资源会获得特殊奖励。</li>
86 <li>长期保持良好的做种习惯将提高您的用户级别。</li>
87 </ul>
88 </Panel>
89 </Collapse>
90 </div>
91);
92
93// 通用版规组件
94const CategoryRules = ({ category }) => {
95 const rules = {
96 movie: "电影资源上传规则...",
97 tv: "剧集资源上传规则...",
98 music: "音乐资源上传规则...",
99 anime: "动漫资源上传规则...",
100 game: "游戏资源上传规则...",
101 variety: "综艺资源上传规则...",
102 sports: "体育资源上传规则...",
103 software: "软件资源上传规则...",
104 learning: "学习资源上传规则...",
105 documentary: "纪录片资源上传规则...",
106 other: "其他资源上传规则...",
107 };
108
109 return (
110 <Collapse className="mb-6">
111 <Panel header={`${category}资源版规`} key="1">
112 <Paragraph>{rules[category] || "暂无特定规则"}</Paragraph>
113 </Panel>
114 </Collapse>
115 );
116};
117
118// 基础表单组件
119const BaseFormItems = ({ category }) => (
120 <>
121 <Form.Item
122 name="torrentFile"
123 label="种子文件"
124 rules={[{ required: true, message: "请上传种子文件" }]}
125 >
126 <Dragger {...uploadProps}>
127 <p className="ant-upload-drag-icon">
128 <InboxOutlined />
129 </p>
130 <p className="ant-upload-text">点击或拖拽种子文件到此区域上传</p>
131 <p className="ant-upload-hint">
132 支持单个.torrent文件上传,请确保种子文件有效
133 </p>
134 </Dragger>
135 </Form.Item>
136
137 <Form.Item
138 name="title"
139 label="标题"
ybtda5978b2025-05-31 15:58:05 +0800140 >
141 <Input placeholder="请输入完整、准确的资源标题" />
142 </Form.Item>
143
144 <Form.Item
145 name="chineseName"
146 label="中文名"
ybtda5978b2025-05-31 15:58:05 +0800147 >
148 <Input placeholder="请输入资源中文名称" />
149 </Form.Item>
150
151 <Form.Item
152 name="englishName"
153 label="英文名/原名"
154 >
155 <Input placeholder="请输入资源英文名称或原名" />
156 </Form.Item>
157
158 <Form.Item
159 name="year"
160 label="年份"
ybtda5978b2025-05-31 15:58:05 +0800161 >
162 <DatePicker picker="year" placeholder="选择年份" />
163 </Form.Item>
164
165 <Form.Item
166 name="region"
167 label="地区"
ybtda5978b2025-05-31 15:58:05 +0800168 >
169 <Select placeholder="请选择地区">
170 <Option value="china">中国大陆</Option>
171 <Option value="hongkong">中国香港</Option>
172 <Option value="taiwan">中国台湾</Option>
173 <Option value="japan">日本</Option>
174 <Option value="korea">韩国</Option>
175 <Option value="usa">美国</Option>
176 <Option value="uk">英国</Option>
177 <Option value="france">法国</Option>
178 <Option value="germany">德国</Option>
179 <Option value="italy">意大利</Option>
180 <Option value="spain">西班牙</Option>
181 <Option value="other">其他</Option>
182 </Select>
183 </Form.Item>
184
185 <Form.Item
186 name="language"
187 label="语言"
ybtda5978b2025-05-31 15:58:05 +0800188 >
189 <Select placeholder="请选择语言" mode="multiple">
190 <Option value="chinese">中文</Option>
191 <Option value="english">英语</Option>
192 <Option value="japanese">日语</Option>
193 <Option value="korean">韩语</Option>
194 <Option value="french">法语</Option>
195 <Option value="german">德语</Option>
196 <Option value="italian">意大利语</Option>
197 <Option value="spanish">西班牙语</Option>
198 <Option value="russian">俄语</Option>
199 <Option value="other">其他</Option>
200 </Select>
201 </Form.Item>
202
203 <Form.Item
204 name="hasSubtitle"
205 valuePropName="checked"
206 >
207 <Checkbox>包含中文字幕</Checkbox>
208 </Form.Item>
209
210 <Form.Item
211 name="description"
212 label="资源简介"
213 rules={[{ required: true, message: "请输入资源简介" }]}
214 >
215 <TextArea rows={6} placeholder="请详细描述资源内容、特点等信息" />
216 </Form.Item>
217
218 <Form.Item
219 name="mediaInfo"
220 label="MediaInfo"
221 >
222 <TextArea rows={4} placeholder="请粘贴MediaInfo信息(如有)" />
223 </Form.Item>
224
225 <Form.Item
226 name="screenshots"
227 label="截图"
228 >
229 <Upload
230 listType="picture-card"
231 action="/api/upload-screenshot"
232 accept=".jpg,.jpeg,.png,.webp"
233 multiple
234 >
235 <div>
236 <UploadOutlined />
237 <div style={{ marginTop: 8 }}>上传截图</div>
238 </div>
239 </Upload>
240 </Form.Item>
241 </>
242);
243
244// 电影特定表单项
245const MovieFormItems = () => (
246 <>
247 <Form.Item
248 name="director"
249 label="导演"
250 >
251 <Input placeholder="请输入导演名称,多个导演请用逗号分隔" />
252 </Form.Item>
253
254 <Form.Item
255 name="actors"
256 label="主演"
257 >
258 <Input placeholder="请输入主演名称,多个主演请用逗号分隔" />
259 </Form.Item>
260
261 <Form.Item
262 name="movieType"
263 label="电影类型"
ybtda5978b2025-05-31 15:58:05 +0800264 >
265 <Select placeholder="请选择电影类型" mode="multiple">
266 <Option value="action">动作</Option>
267 <Option value="comedy">喜剧</Option>
268 <Option value="romance">爱情</Option>
269 <Option value="sci-fi">科幻</Option>
270 <Option value="horror">恐怖</Option>
271 <Option value="drama">剧情</Option>
272 <Option value="war">战争</Option>
273 <Option value="documentary">纪录</Option>
274 <Option value="animation">动画</Option>
275 <Option value="thriller">惊悚</Option>
276 <Option value="crime">犯罪</Option>
277 <Option value="fantasy">奇幻</Option>
278 <Option value="adventure">冒险</Option>
279 <Option value="history">历史</Option>
280 <Option value="other">其他</Option>
281 </Select>
282 </Form.Item>
283
284 <Form.Item
285 name="resolution"
286 label="分辨率"
ybtda5978b2025-05-31 15:58:05 +0800287 >
288 <Select placeholder="请选择分辨率">
289 <Option value="4K">4K</Option>
290 <Option value="2K">2K</Option>
291 <Option value="1080p">1080p</Option>
292 <Option value="720p">720p</Option>
293 <Option value="480p">480p</Option>
294 <Option value="other">其他</Option>
295 </Select>
296 </Form.Item>
297
298 <Form.Item
299 name="source"
300 label="片源"
ybtda5978b2025-05-31 15:58:05 +0800301 >
302 <Select placeholder="请选择片源">
303 <Option value="bluray">蓝光原盘</Option>
304 <Option value="remux">蓝光重灌</Option>
305 <Option value="encode">压制</Option>
306 <Option value="web-dl">WEB-DL</Option>
307 <Option value="dvd">DVD</Option>
308 <Option value="hdtv">HDTV</Option>
309 <Option value="other">其他</Option>
310 </Select>
311 </Form.Item>
312
313 <Form.Item
314 name="duration"
315 label="片长(分钟)"
316 >
317 <InputNumber min={1} placeholder="请输入片长" />
318 </Form.Item>
319
320 <Form.Item
321 name="imdbId"
322 label="IMDb ID"
323 >
324 <Input placeholder="例如:tt0111161" />
325 </Form.Item>
326
327 <Form.Item
328 name="doubanId"
329 label="豆瓣ID"
330 >
331 <Input placeholder="例如:1292052" />
332 </Form.Item>
333 </>
334);
335
336// 剧集特定表单项
337const TVFormItems = () => (
338 <>
339 <Form.Item
340 name="season"
341 label="季数"
342 >
343 <InputNumber min={1} placeholder="第几季" />
344 </Form.Item>
345
346 <Form.Item
347 name="episode"
348 label="集数"
349 >
350 <Input placeholder="例如:1-12、全集、SP" />
351 </Form.Item>
352
353 <Form.Item
354 name="isComplete"
355 valuePropName="checked"
356 >
357 <Checkbox>已完结</Checkbox>
358 </Form.Item>
359
360 <Form.Item
361 name="director"
362 label="导演"
363 >
364 <Input placeholder="请输入导演名称,多个导演请用逗号分隔" />
365 </Form.Item>
366
367 <Form.Item
368 name="actors"
369 label="主演"
370 >
371 <Input placeholder="请输入主演名称,多个主演请用逗号分隔" />
372 </Form.Item>
373
374 <Form.Item
375 name="tvType"
376 label="剧集类型"
377 rules={[{ required: true, message: "请选择剧集类型" }]}
378 >
379 <Select placeholder="请选择剧集类型" mode="multiple">
380 <Option value="action">动作</Option>
381 <Option value="comedy">喜剧</Option>
382 <Option value="romance">爱情</Option>
383 <Option value="sci-fi">科幻</Option>
384 <Option value="horror">恐怖</Option>
385 <Option value="drama">剧情</Option>
386 <Option value="crime">犯罪</Option>
387 <Option value="fantasy">奇幻</Option>
388 <Option value="adventure">冒险</Option>
389 <Option value="mystery">悬疑</Option>
390 <Option value="thriller">惊悚</Option>
391 <Option value="other">其他</Option>
392 </Select>
393 </Form.Item>
394
395 <Form.Item
396 name="resolution"
397 label="分辨率"
398 rules={[{ required: true, message: "请选择分辨率" }]}
399 >
400 <Select placeholder="请选择分辨率">
401 <Option value="4K">4K</Option>
402 <Option value="2K">2K</Option>
403 <Option value="1080p">1080p</Option>
404 <Option value="720p">720p</Option>
405 <Option value="480p">480p</Option>
406 <Option value="other">其他</Option>
407 </Select>
408 </Form.Item>
409
410 <Form.Item
411 name="source"
412 label="片源"
413 rules={[{ required: true, message: "请选择片源" }]}
414 >
415 <Select placeholder="请选择片源">
416 <Option value="bluray">蓝光原盘</Option>
417 <Option value="remux">蓝光重灌</Option>
418 <Option value="encode">压制</Option>
419 <Option value="web-dl">WEB-DL</Option>
420 <Option value="dvd">DVD</Option>
421 <Option value="hdtv">HDTV</Option>
422 <Option value="other">其他</Option>
423 </Select>
424 </Form.Item>
425
426 <Form.Item
427 name="imdbId"
428 label="IMDb ID"
429 >
430 <Input placeholder="例如:tt0111161" />
431 </Form.Item>
432
433 <Form.Item
434 name="doubanId"
435 label="豆瓣ID"
436 >
437 <Input placeholder="例如:1292052" />
438 </Form.Item>
439 </>
440);
441
442// 音乐特定表单项
443const MusicFormItems = () => (
444 <>
445 <Form.Item
446 name="artist"
447 label="艺术家"
448 rules={[{ required: true, message: "请输入艺术家名称" }]}
449 >
450 <Input placeholder="请输入艺术家名称" />
451 </Form.Item>
452
453 <Form.Item
454 name="album"
455 label="专辑名称"
456 >
457 <Input placeholder="请输入专辑名称(如果是专辑)" />
458 </Form.Item>
459
460 <Form.Item
461 name="musicType"
462 label="音乐类型"
463 rules={[{ required: true, message: "请选择音乐类型" }]}
464 >
465 <Select placeholder="请选择音乐类型" mode="multiple">
466 <Option value="pop">流行</Option>
467 <Option value="rock">摇滚</Option>
468 <Option value="electronic">电子</Option>
469 <Option value="folk">民谣</Option>
470 <Option value="hip-hop">嘻哈</Option>
471 <Option value="classical">古典</Option>
472 <Option value="jazz">爵士</Option>
473 <Option value="soundtrack">原声带</Option>
474 <Option value="other">其他</Option>
475 </Select>
476 </Form.Item>
477
478 <Form.Item
479 name="format"
480 label="音频格式"
481 rules={[{ required: true, message: "请选择音频格式" }]}
482 >
483 <Select placeholder="请选择音频格式">
484 <Option value="flac">FLAC</Option>
485 <Option value="ape">APE</Option>
486 <Option value="wav">WAV</Option>
487 <Option value="mp3">MP3</Option>
488 <Option value="aac">AAC</Option>
489 <Option value="other">其他</Option>
490 </Select>
491 </Form.Item>
492
493 <Form.Item
494 name="bitrate"
495 label="比特率"
496 >
497 <Select placeholder="请选择比特率">
498 <Option value="lossless">无损</Option>
499 <Option value="320">320Kbps</Option>
500 <Option value="256">256Kbps</Option>
501 <Option value="192">192Kbps</Option>
502 <Option value="128">128Kbps</Option>
503 <Option value="other">其他</Option>
504 </Select>
505 </Form.Item>
506
507 <Form.Item
508 name="tracks"
509 label="曲目数"
510 >
511 <InputNumber min={1} placeholder="请输入曲目数量" />
512 </Form.Item>
513 </>
514);
515
516// 动漫特定表单项
517const AnimeFormItems = () => (
518 <>
519 <Form.Item
520 name="season"
521 label="季数"
522 >
523 <InputNumber min={1} placeholder="第几季" />
524 </Form.Item>
525
526 <Form.Item
527 name="episode"
528 label="集数"
529 >
530 <Input placeholder="例如:1-12、全集、SP、剧场版" />
531 </Form.Item>
532
533 <Form.Item
534 name="isComplete"
535 valuePropName="checked"
536 >
537 <Checkbox>已完结</Checkbox>
538 </Form.Item>
539
540 <Form.Item
541 name="animeType"
542 label="动漫类型"
543 rules={[{ required: true, message: "请选择动漫类型" }]}
544 >
545 <Select placeholder="请选择动漫类型" mode="multiple">
546 <Option value="tv">TV版</Option>
547 <Option value="movie">剧场版</Option>
548 <Option value="ova">OVA</Option>
549 <Option value="special">特别篇</Option>
550 </Select>
551 </Form.Item>
552
553 <Form.Item
554 name="resolution"
555 label="分辨率"
556 rules={[{ required: true, message: "请选择分辨率" }]}
557 >
558 <Select placeholder="请选择分辨率">
559 <Option value="4K">4K</Option>
560 <Option value="2K">2K</Option>
561 <Option value="1080p">1080p</Option>
562 <Option value="720p">720p</Option>
563 <Option value="480p">480p</Option>
564 <Option value="other">其他</Option>
565 </Select>
566 </Form.Item>
567
568 <Form.Item
569 name="source"
570 label="片源"
571 rules={[{ required: true, message: "请选择片源" }]}
572 >
573 <Select placeholder="请选择片源">
574 <Option value="bluray">蓝光原盘</Option>
575 <Option value="remux">蓝光重灌</Option>
576 <Option value="encode">压制</Option>
577 <Option value="web-dl">WEB-DL</Option>
578 <Option value="dvd">DVD</Option>
579 <Option value="hdtv">HDTV</Option>
580 <Option value="other">其他</Option>
581 </Select>
582 </Form.Item>
583
584 <Form.Item
585 name="subTeam"
586 label="字幕组"
587 >
588 <Input placeholder="请输入字幕组名称" />
589 </Form.Item>
590 </>
591);
592
593// 游戏特定表单项
594const GameFormItems = () => (
595 <>
596 <Form.Item
597 name="platform"
598 label="平台"
599 rules={[{ required: true, message: "请选择游戏平台" }]}
600 >
601 <Select placeholder="请选择游戏平台" mode="multiple">
602 <Option value="pc">PC</Option>
603 <Option value="ps5">PS5</Option>
604 <Option value="ps4">PS4</Option>
605 <Option value="ps3">PS3</Option>
606 <Option value="xbox-series">Xbox Series X/S</Option>
607 <Option value="xbox-one">Xbox One</Option>
608 <Option value="switch">Nintendo Switch</Option>
609 <Option value="ns">Nintendo Switch</Option>
610 <Option value="3ds">Nintendo 3DS</Option>
611 <Option value="mobile">手机</Option>
612 <Option value="other">其他</Option>
613 </Select>
614 </Form.Item>
615
616 <Form.Item
617 name="gameType"
618 label="游戏类型"
619 rules={[{ required: true, message: "请选择游戏类型" }]}
620 >
621 <Select placeholder="请选择游戏类型" mode="multiple">
622 <Option value="rpg">角色扮演</Option>
623 <Option value="action">动作</Option>
624 <Option value="fps">第一人称射击</Option>
625 <Option value="tps">第三人称射击</Option>
626 <Option value="strategy">策略</Option>
627 <Option value="simulation">模拟</Option>
628 <Option value="adventure">冒险</Option>
629 <Option value="sports">体育</Option>
630 <Option value="racing">竞速</Option>
631 <Option value="fighting">格斗</Option>
632 <Option value="other">其他</Option>
633 </Select>
634 </Form.Item>
635
636 <Form.Item
637 name="version"
638 label="版本"
639 >
640 <Input placeholder="请输入游戏版本,例如:V1.02.3" />
641 </Form.Item>
642
643 <Form.Item
644 name="developer"
645 label="开发商"
646 >
647 <Input placeholder="请输入游戏开发商" />
648 </Form.Item>
649
650 <Form.Item
651 name="publisher"
652 label="发行商"
653 >
654 <Input placeholder="请输入游戏发行商" />
655 </Form.Item>
656
657 <Form.Item
658 name="language"
659 label="语言"
660 rules={[{ required: true, message: "请选择游戏语言" }]}
661 >
662 <Select placeholder="请选择游戏语言" mode="multiple">
663 <Option value="chinese">中文</Option>
664 <Option value="english">英文</Option>
665 <Option value="japanese">日文</Option>
666 <Option value="korean">韩文</Option>
667 <Option value="french">法文</Option>
668 <Option value="german">德文</Option>
669 <Option value="russian">俄文</Option>
670 <Option value="multi">多语言</Option>
671 </Select>
672 </Form.Item>
673
674 <Form.Item
675 name="hasCrack"
676 valuePropName="checked"
677 >
678 <Checkbox>已破解/免安装</Checkbox>
679 </Form.Item>
680 </>
681);
682
683// 其他类型特定的表单项(简化)
684const OtherFormItems = ({ category }) => {
685 if (category === "variety") {
686 return (
687 <>
688 <Form.Item name="host" label="主持人">
689 <Input placeholder="请输入主持人名称" />
690 </Form.Item>
691 <Form.Item name="episode" label="期数">
692 <Input placeholder="例如:第1-12期、20200101" />
693 </Form.Item>
694 </>
695 );
696 }
697
698 if (category === "sports") {
699 return (
700 <>
701 <Form.Item name="league" label="联赛/赛事名称">
702 <Input placeholder="请输入联赛或赛事名称" />
703 </Form.Item>
704 <Form.Item name="match" label="比赛">
705 <Input placeholder="例如:队伍A vs 队伍B" />
706 </Form.Item>
707 </>
708 );
709 }
710
711 if (category === "software") {
712 return (
713 <>
714 <Form.Item name="version" label="版本">
715 <Input placeholder="请输入软件版本" />
716 </Form.Item>
717 <Form.Item name="os" label="操作系统">
718 <Select placeholder="请选择操作系统" mode="multiple">
719 <Option value="windows">Windows</Option>
720 <Option value="macos">macOS</Option>
721 <Option value="linux">Linux</Option>
722 <Option value="android">Android</Option>
723 <Option value="ios">iOS</Option>
724 </Select>
725 </Form.Item>
726 </>
727 );
728 }
729
730 if (category === "learning") {
731 return (
732 <>
733 <Form.Item name="subject" label="学科/主题">
734 <Input placeholder="请输入学科或主题" />
735 </Form.Item>
736 <Form.Item name="level" label="难度级别">
737 <Select placeholder="请选择难度级别">
738 <Option value="beginner">入门</Option>
739 <Option value="intermediate">中级</Option>
740 <Option value="advanced">高级</Option>
741 </Select>
742 </Form.Item>
743 </>
744 );
745 }
746
747 if (category === "documentary") {
748 return (
749 <>
750 <Form.Item name="docType" label="纪录片类型">
751 <Select placeholder="请选择纪录片类型" mode="multiple">
752 <Option value="nature">自然</Option>
753 <Option value="history">历史</Option>
754 <Option value="science">科学</Option>
755 <Option value="culture">人文</Option>
756 <Option value="society">社会</Option>
757 <Option value="biography">传记</Option>
758 </Select>
759 </Form.Item>
760 <Form.Item name="episodes" label="集数">
761 <Input placeholder="例如:共8集" />
762 </Form.Item>
763 </>
764 );
765 }
766
767 return null;
768};
769
770// 主组件
771const UploadTorrentPage = () => {
772 const [form] = Form.useForm();
773 const [activeCategory, setActiveCategory] = useState("notice");
ybtff3665a2025-06-09 23:53:39 +0800774 const { user } = useAuth();
ybtda5978b2025-05-31 15:58:05 +0800775
ybtff3665a2025-06-09 23:53:39 +0800776 const onFinish = async (values) => {
777 try {
778 // 创建 FormData 对象
779 const formData = new FormData();
780
781 // * 添加用户名
782 const username = user?.username || user?.uid;
783 if (!username) {
784 message.error('用户信息不完整,请重新登录');
785 return;
786 }
787 formData.append('username', username);
788
789 // 添加描述信息
790 formData.append('description', values.description || '');
791
792 // 添加种子文件
793 if (values.torrentFile && values.torrentFile.fileList && values.torrentFile.fileList.length > 0) {
794 const torrentFile = values.torrentFile.fileList[0].originFileObj;
795 formData.append('torrent', torrentFile);
796 } else {
797 message.error('请选择种子文件');
798 return;
799 }
800
801 console.log('username', formData.get('username'));
802 console.log('description', formData.get('description'));
803 console.log('torrent', formData.get('torrent'));
804 // 调用上传接口
805 const response = await uploadTorrent(formData);
806
807 if (response && response.message === "Resource published successfully") {
808 message.success('种子上传成功!');
809 form.resetFields(); // 重置表单
810 } else {
811 message.error('上传失败,请重试');
812 }
813 } catch (error) {
814 console.error('上传种子时出错:', error);
815 message.error('上传失败:' + (error.message || '网络错误,请重试'));
816 }
ybtda5978b2025-05-31 15:58:05 +0800817 };
818
819 const renderFormByCategory = (category) => {
820 if (category === "notice") {
821 return <NoticeContent />;
822 }
823
824 return (
825 <Form
826 form={form}
827 layout="vertical"
828 onFinish={onFinish}
829 scrollToFirstError
830 >
831 <CategoryRules category={category} />
832
833 <BaseFormItems category={category} />
834
835 {/* 根据类别渲染特定的表单项 */}
836 {category === "movie" && <MovieFormItems />}
837 {category === "tv" && <TVFormItems />}
838 {category === "music" && <MusicFormItems />}
839 {category === "anime" && <AnimeFormItems />}
840 {category === "game" && <GameFormItems />}
841 {["variety", "sports", "software", "learning", "documentary", "other"].includes(category) && (
842 <OtherFormItems category={category} />
843 )}
844
845 <Divider />
846
847 <Form.Item>
848 <Space>
849 <Button type="primary" htmlType="submit">
850 提交
851 </Button>
852 <Button onClick={() => form.resetFields()}>重置</Button>
853 </Space>
854 </Form.Item>
855 </Form>
856 );
857 };
858
859 return (
860 <div className="space-y-6">
861 <Title level={2}>发布种子</Title>
862
863 <Tabs activeKey={activeCategory} onChange={setActiveCategory} type="card">
864 <TabPane tab="注意事项" key="notice" />
865 <TabPane tab="电影" key="movie" />
866 <TabPane tab="剧集" key="tv" />
867 <TabPane tab="音乐" key="music" />
868 <TabPane tab="动漫" key="anime" />
869 <TabPane tab="游戏" key="game" />
870 <TabPane tab="综艺" key="variety" />
871 <TabPane tab="体育" key="sports" />
872 <TabPane tab="软件" key="software" />
873 <TabPane tab="学习" key="learning" />
874 <TabPane tab="纪录片" key="documentary" />
875 <TabPane tab="其他" key="other" />
876 </Tabs>
877
878 <div>{renderFormByCategory(activeCategory)}</div>
879 </div>
880 );
881};
882
883export default UploadTorrentPage;