blob: 0aa24fb0ed9558e00964560471ad98cccb5df353 [file] [log] [blame]
Krishyaf1d0ea82025-05-03 17:01:58 +08001import React, { useState } from 'react';
2import axios from 'axios';
Krishya7ec1dd02025-04-19 15:29:03 +08003import { Edit } from '@icon-park/react';
4import './CreatePostButton.css';
22301009df48f962025-06-05 13:40:44 +08005import { useUser } from '../../../../context/UserContext';
Krishya7ec1dd02025-04-19 15:29:03 +08006
Krishyab5ef96d2025-06-05 13:57:05 +08007const user = JSON.parse(localStorage.getItem('user')); // user = { user_id: 123, ... }
8const userId = user?.userId;
9
10
Krishyaf1d0ea82025-05-03 17:01:58 +080011const CreatePostButton = () => {
22301009df48f962025-06-05 13:40:44 +080012 const { user } = useUser();
13 const userId = user?.userId; // 这里改为 userId,跟 UserContext 统一
Krishyaf1d0ea82025-05-03 17:01:58 +080014
22301009df48f962025-06-05 13:40:44 +080015 const [showModal, setShowModal] = useState(false);
Krishyaf1d0ea82025-05-03 17:01:58 +080016 const [title, setTitle] = useState('');
17 const [content, setContent] = useState('');
18 const [previewUrls, setPreviewUrls] = useState([]);
Krishya2283d882025-05-27 22:25:19 +080019 const [files, setFiles] = useState([]);
Krishyaf1d0ea82025-05-03 17:01:58 +080020
Krishya2283d882025-05-27 22:25:19 +080021 const handleImageChange = (e) => {
22 const selectedFiles = Array.from(e.target.files);
23 if (!selectedFiles.length) return;
24 setFiles(selectedFiles);
25 setPreviewUrls(selectedFiles.map(f => URL.createObjectURL(f)));
Krishyaf1d0ea82025-05-03 17:01:58 +080026 };
27
Krishyaf1d0ea82025-05-03 17:01:58 +080028 const handleSubmit = async () => {
22301009df48f962025-06-05 13:40:44 +080029 if (!userId) {
30 alert('用户未登录或用户ID未获取到,无法发帖');
31 return;
32 }
Krishyaf1d0ea82025-05-03 17:01:58 +080033 if (!title.trim() || !content.trim()) {
34 alert('标题和内容均为必填项');
35 return;
36 }
37
Krishya2283d882025-05-27 22:25:19 +080038 const formData = new FormData();
39 formData.append('title', title.trim());
40 formData.append('postContent', content.trim());
41
42 files.forEach(file => {
22301009df48f962025-06-05 13:40:44 +080043 formData.append('imageUrl', file);
Krishya2283d882025-05-27 22:25:19 +080044 });
45
Krishyaf1d0ea82025-05-03 17:01:58 +080046 try {
47 await axios.post(
Krishya2283d882025-05-27 22:25:19 +080048 `/echo/forum/posts/${userId}/createPost`,
49 formData,
Krishyaf1d0ea82025-05-03 17:01:58 +080050 {
Krishya2283d882025-05-27 22:25:19 +080051 headers: { 'Content-Type': 'multipart/form-data' }
Krishyaf1d0ea82025-05-03 17:01:58 +080052 }
53 );
Krishya2283d882025-05-27 22:25:19 +080054
Krishyaf1d0ea82025-05-03 17:01:58 +080055 setTitle('');
56 setContent('');
Krishya2283d882025-05-27 22:25:19 +080057 setFiles([]);
Krishyaf1d0ea82025-05-03 17:01:58 +080058 setPreviewUrls([]);
Krishyaf1d0ea82025-05-03 17:01:58 +080059 setShowModal(false);
60 alert('发帖成功');
Krishyaf1d0ea82025-05-03 17:01:58 +080061 } catch (err) {
62 console.error('发帖失败:', err.response?.data || err);
63 alert(err.response?.data?.error || '发帖失败,请稍后重试');
64 }
Krishya7ec1dd02025-04-19 15:29:03 +080065 };
66
67 return (
Krishyaf1d0ea82025-05-03 17:01:58 +080068 <>
69 <div className="create-post">
70 <button onClick={() => setShowModal(true)} className="create-btn">
71 <Edit theme="outline" size="18" style={{ marginRight: 6 }} />
72 发帖
73 </button>
74 </div>
75
76 {showModal && (
77 <div className="cp-modal-overlay" onClick={() => setShowModal(false)}>
78 <div className="cp-modal-dialog" onClick={e => e.stopPropagation()}>
79 <h3>创建新帖子</h3>
80
81 <input
82 type="text"
83 placeholder="帖子标题"
84 value={title}
85 onChange={e => setTitle(e.target.value)}
86 />
87
88 <textarea
89 placeholder="正文内容"
90 value={content}
91 onChange={e => setContent(e.target.value)}
92 />
93
94 <label className="file-label">
95 选择图片
96 <input
97 type="file"
98 accept="image/*"
99 multiple
100 onChange={handleImageChange}
101 style={{ display: 'none' }}
102 />
103 </label>
104
105 <div className="cp-preview">
106 {previewUrls.map((url, i) => (
Krishya2283d882025-05-27 22:25:19 +0800107 <img key={i} src={url} alt={`预览 ${i}`} />
Krishyaf1d0ea82025-05-03 17:01:58 +0800108 ))}
109 </div>
110
111 <div className="cp-actions">
112 <button className="btn cancel" onClick={() => setShowModal(false)}>
113 取消
114 </button>
115 <button className="btn submit" onClick={handleSubmit}>
116 发布
117 </button>
118 </div>
119 </div>
120 </div>
121 )}
122 </>
Krishya7ec1dd02025-04-19 15:29:03 +0800123 );
124};
125
126export default CreatePostButton;