修改提示框样式、完成付费片单、推荐跳转
Change-Id: Ie84c53d4e306435144b1f26ceb39cc182e99d57a
diff --git a/src/pages/SeedList/Recommend/CreatePlaylistModal.jsx b/src/pages/SeedList/Recommend/CreatePlaylistModal.jsx
new file mode 100644
index 0000000..60a5b76
--- /dev/null
+++ b/src/pages/SeedList/Recommend/CreatePlaylistModal.jsx
@@ -0,0 +1,153 @@
+import React, { useState } from 'react';
+import axios from 'axios';
+import toast from 'react-hot-toast';
+import TorrentSelector from './TorrentSelector'; // 引入种子选择组件
+import './CreatePlaylistModal.css';
+import { uploadFile } from '../../../api/file';
+
+const CreatePlaylistModal = ({ onClose, onSuccess }) => {
+ const [newPlaylist, setNewPlaylist] = useState({
+ title: '',
+ price: '',
+ description: '',
+ torrentList: [], // 选中的种子ID数组
+ });
+
+ const [coverFile, setCoverFile] = useState(null); // 新增封面文件状态
+ const [previewUrl, setPreviewUrl] = useState(''); // 封面预览URL
+
+ const handleSelect = (id, checked) => {
+ setNewPlaylist(prev => {
+ let newList = [...prev.torrentList];
+ if (checked) {
+ if (!newList.includes(id)) newList.push(id);
+ } else {
+ newList = newList.filter(i => i !== id);
+ }
+ return { ...prev, torrentList: newList };
+ });
+ };
+
+ const handleCoverChange = (e) => {
+ const file = e.target.files?.[0];
+ if (file) {
+ setCoverFile(file);
+ setPreviewUrl(URL.createObjectURL(file)); // 生成预览图
+ } else {
+ setCoverFile(null);
+ setPreviewUrl('');
+ }
+ };
+
+ const handleCreate = async () => {
+ const { title, price, description, torrentList } = newPlaylist;
+
+ if (!title.trim()) {
+ toast.error('标题不能为空');
+ return;
+ }
+ if (!price || isNaN(Number(price)) || Number(price) < 0) {
+ toast.error('请输入合法的价格');
+ return;
+ }
+ if (torrentList.length === 0) {
+ toast.error('请至少选择一个种子');
+ return;
+ }
+
+ const toastId = toast.loading('正在创建...');
+ const playlistData = { title, price, description, torrentList }; // 构建片单数据
+
+ try {
+
+ if (coverFile) {
+ const { data } = await uploadFile(coverFile);
+ if (data.code === 0) {
+ playlistData['coverUrl'] = data.data;
+ } else {
+ toast.error('封面上传失败: ' + data.msg, { id: toastId});
+ return;
+ }
+ }
+
+ const res = await axios.post('/playlist', playlistData, {
+ });
+
+ if (res.data.code === 0) {
+ toast.success('片单创建成功', { id: toastId });
+ onSuccess(res.data.data);
+ onClose();
+ } else {
+ toast.error(`创建失败:${res.data.msg}`, { id: toastId });
+ }
+ } catch (err) {
+ console.error('创建片单失败', err);
+ toast.error('创建失败,请稍后重试', { id: toastId });
+ }
+ };
+
+ return (
+ <div className="modal-overlay create-playlist-modal">
+ <div className="modal">
+ <h3>创建新片单</h3>
+
+ <label>
+ 标题:
+ <input
+ type="text"
+ value={newPlaylist.title}
+ onChange={(e) => setNewPlaylist({ ...newPlaylist, title: e.target.value })}
+ />
+ </label>
+
+ <label>
+ 封面图:
+ <input
+ type="file"
+ accept="image/*"
+ onChange={handleCoverChange}
+ />
+ {previewUrl && (
+ <div style={{ marginTop: '10px' }}>
+ <img src={previewUrl} alt="封面预览" style={{ maxWidth: '100%', maxHeight: '150px' }} />
+ </div>
+ )}
+ </label>
+
+ <label>
+ 价格(元):
+ <input
+ type="number"
+ step="0.01"
+ min="0"
+ value={newPlaylist.price}
+ onChange={(e) => setNewPlaylist({ ...newPlaylist, price: e.target.value })}
+ />
+ </label>
+
+ <label>
+ 片单描述:
+ <textarea
+ value={newPlaylist.description}
+ onChange={(e) => setNewPlaylist({ ...newPlaylist, description: e.target.value })}
+ />
+ </label>
+
+ <label>
+ 关联种子选择:
+ <TorrentSelector
+ selectedIds={newPlaylist.torrentList}
+ onSelect={handleSelect}
+ />
+ </label>
+
+ <div className="modal-actions">
+ <button onClick={handleCreate}>提交</button>
+ <button onClick={onClose}>取消</button>
+ </div>
+ </div>
+ </div>
+ );
+};
+
+export default CreatePlaylistModal;