| import React, { useState } from 'react'; |
| import axios from 'axios'; |
| import { Edit } from '@icon-park/react'; |
| import './CreatePostButton.css'; |
| |
| const API_BASE = process.env.REACT_APP_API_BASE; |
| const USER_ID = 456; |
| |
| const CreatePostButton = () => { |
| const [showModal, setShowModal] = useState(false); |
| |
| // 表单字段 |
| const [title, setTitle] = useState(''); |
| const [content, setContent] = useState(''); |
| const [previewUrls, setPreviewUrls] = useState([]); |
| const [imageUrls, setImageUrls] = useState([]); |
| |
| // 处理文件选中:预览 & 上传 |
| const handleImageChange = async (e) => { |
| const files = Array.from(e.target.files); |
| if (!files.length) return; |
| // 本地预览 |
| setPreviewUrls(files.map(f => URL.createObjectURL(f))); |
| |
| // 并发上传,假设 /upload 接口返回 { url: '...' } |
| try { |
| const uploaded = await Promise.all( |
| files.map(file => { |
| const fd = new FormData(); |
| fd.append('file', file); |
| return axios.post(`${API_BASE}/upload`, fd, { |
| headers: { 'Content-Type': 'multipart/form-data' } |
| }).then(res => res.data.url); |
| }) |
| ); |
| setImageUrls(uploaded); |
| } catch (err) { |
| console.error('图片上传失败:', err); |
| alert('封面图上传失败,请重试'); |
| } |
| }; |
| |
| // 提交发帖 |
| const handleSubmit = async () => { |
| if (!title.trim() || !content.trim()) { |
| alert('标题和内容均为必填项'); |
| return; |
| } |
| |
| try { |
| await axios.post( |
| `${API_BASE}/echo/forum/posts/${USER_ID}/createPost`, |
| { |
| title: title.trim(), |
| post_content: content.trim(), |
| image_url: imageUrls |
| } |
| ); |
| // 重置状态并关闭 |
| setTitle(''); |
| setContent(''); |
| setPreviewUrls([]); |
| setImageUrls([]); |
| setShowModal(false); |
| alert('发帖成功'); |
| // 如需刷新帖子列表,可在这里触发外部回调 |
| } catch (err) { |
| console.error('发帖失败:', err.response?.data || err); |
| alert(err.response?.data?.error || '发帖失败,请稍后重试'); |
| } |
| }; |
| |
| return ( |
| <> |
| <div className="create-post"> |
| <button onClick={() => setShowModal(true)} className="create-btn"> |
| <Edit theme="outline" size="18" style={{ marginRight: 6 }} /> |
| 发帖 |
| </button> |
| </div> |
| |
| {showModal && ( |
| <div className="cp-modal-overlay" onClick={() => setShowModal(false)}> |
| <div className="cp-modal-dialog" onClick={e => e.stopPropagation()}> |
| <h3>创建新帖子</h3> |
| |
| <input |
| type="text" |
| placeholder="帖子标题" |
| value={title} |
| onChange={e => setTitle(e.target.value)} |
| /> |
| |
| <textarea |
| placeholder="正文内容" |
| value={content} |
| onChange={e => setContent(e.target.value)} |
| /> |
| |
| <label className="file-label"> |
| 选择图片 |
| <input |
| type="file" |
| accept="image/*" |
| multiple |
| onChange={handleImageChange} |
| style={{ display: 'none' }} |
| /> |
| </label> |
| |
| <div className="cp-preview"> |
| {previewUrls.map((url, i) => ( |
| <img key={i} src={url} alt={`封面预览 ${i}`} /> |
| ))} |
| </div> |
| |
| <div className="cp-actions"> |
| <button className="btn cancel" onClick={() => setShowModal(false)}> |
| 取消 |
| </button> |
| <button className="btn submit" onClick={handleSubmit}> |
| 发布 |
| </button> |
| </div> |
| </div> |
| </div> |
| )} |
| </> |
| ); |
| }; |
| |
| export default CreatePostButton; |