修改好友动态、发布动态、促销模块、创建帖子,Resolve review.

Change-Id: I84a2460dd1208bc703b0527d98225204d03e5efc
diff --git a/src/pages/Forum/posts-main/components/CreatePostButton.css b/src/pages/Forum/posts-main/components/CreatePostButton.css
index b40b9e7..225ddde 100644
--- a/src/pages/Forum/posts-main/components/CreatePostButton.css
+++ b/src/pages/Forum/posts-main/components/CreatePostButton.css
@@ -1,19 +1,127 @@
 .create-post {
-    display: flex;
-    justify-content: center;
-    margin: 20px 0;
-  }
-  
-  .create-btn {
-    background-color: #BA929A;
-    color: white;
-    padding: 10px 20px;
-    border-radius: 8px;
-    border: none;
-    cursor: pointer;
-    font-size: 16px;
-    transition: background-color 0.3s ease;
-  }
+  display: flex;
+  justify-content: center;
+  margin: 20px 0;
+}
 
-  
-  
\ No newline at end of file
+.create-btn {
+  background-color: #BA929A;
+  color: white;
+  padding: 10px 20px;
+  border-radius: 8px;
+  border: none;
+  cursor: pointer;
+  font-size: 16px;
+  display: flex;
+  align-items: center;
+  transition: background-color 0.3s ease;
+}
+
+.create-btn:hover {
+  background-color: #a17b83;
+}
+
+/* Modal 样式 */
+.cp-modal-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0,0,0,0.5);
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  z-index: 1000;
+}
+
+.cp-modal-dialog {
+  background: #e9ded2;
+  padding: 20px;
+  width: 35%;
+  max-width: 500px;
+  border-radius: 8px;
+  display: flex;
+  flex-direction: column;
+  gap: 20px;
+}
+
+/* 标题 */
+.cp-modal-dialog h3 {
+  margin: 0;
+  color : #4A3B34;
+}
+
+/* 文本输入和文本域 —— 宽度保持 97%,一致感更强 */
+.cp-modal-dialog input[type="text"],
+.cp-modal-dialog textarea,
+.cp-modal-dialog input[type="file"] {
+  width: 97%;
+  padding: 8px;
+  font-size: 14px;
+  border: 1px solid #ccc;
+  border-radius: 4px;
+}
+
+/* 文本域高度 */
+.cp-modal-dialog textarea {
+  resize: vertical;
+  min-height: 80px;
+}
+
+/* 文件选择按钮保持 label 方式,不变 */
+.file-label {
+  display: inline-block;
+  padding: 6px 10px;
+  background: #BA929A;
+  color: #fff;
+  border-radius: 4px;
+  cursor: pointer;
+  font-size: 14px;
+  user-select: none;
+  width : 12%;
+}
+
+.file-label:hover {
+  background: #a17b83;
+}
+
+/* 预览区 */
+.cp-preview {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+}
+
+.cp-preview img {
+  width: 80px;
+  height: 80px;
+  object-fit: cover;
+  border-radius: 4px;
+  border: 1px solid #bbb;
+}
+
+/* 按钮组 —— 同 .modal-actions */
+.cp-actions {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 10px;
+}
+
+.cp-actions .btn {
+  padding: 6px 12px;
+  font-size: 14px;
+  cursor: pointer;
+  border: none;
+  border-radius: 4px;
+}
+
+.cp-actions .btn.cancel {
+  background: #5F4437;
+  color: #fff;
+}
+
+.cp-actions .btn.submit {
+  background: #BA929A;
+  color: #fff;
+}
diff --git a/src/pages/Forum/posts-main/components/CreatePostButton.jsx b/src/pages/Forum/posts-main/components/CreatePostButton.jsx
index 0632173..0390ee7 100644
--- a/src/pages/Forum/posts-main/components/CreatePostButton.jsx
+++ b/src/pages/Forum/posts-main/components/CreatePostButton.jsx
@@ -1,21 +1,131 @@
-import React from 'react';
-import { useLocation } from 'wouter';
+import React, { useState } from 'react';
+import axios from 'axios';
 import { Edit } from '@icon-park/react';
 import './CreatePostButton.css';
 
-const CreatePostButton = () => {
-  const [, navigate] = useLocation();
+const API_BASE = process.env.REACT_APP_API_BASE;
+const USER_ID = 456;
 
-  const goToCreatePost = () => {
-    navigate('/forum/create-post');
+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={goToCreatePost} className="create-btn">
-        <Edit theme="outline" size="18" /> 发帖
-      </button>
-    </div>
+    <>
+      <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>
+      )}
+    </>
   );
 };
 
diff --git a/src/pages/Forum/posts-main/components/SearchBar.css b/src/pages/Forum/posts-main/components/SearchBar.css
index 60ba679..2a8349d 100644
--- a/src/pages/Forum/posts-main/components/SearchBar.css
+++ b/src/pages/Forum/posts-main/components/SearchBar.css
@@ -11,7 +11,7 @@
     margin-right: -3px;
     background-color: #e9ded2;
     /* 文字颜色 */
-    color: #4b322b;
+    color: #4A3B34;
     padding: 8px 10px;     /* 控制按钮的高度和宽度 */
     font-size: 15px;       /* 控制文字大小 */
   }
diff --git a/src/pages/Forum/posts-main/components/SearchBar.jsx b/src/pages/Forum/posts-main/components/SearchBar.jsx
index 52b873d..281d578 100644
--- a/src/pages/Forum/posts-main/components/SearchBar.jsx
+++ b/src/pages/Forum/posts-main/components/SearchBar.jsx
@@ -16,7 +16,7 @@
         type="text"
         value={query}
         onChange={e => setQuery(e.target.value)}
-        placeholder="标题"
+        placeholder="输入要搜索的帖子"
         className="search-input"
       />
       <button onClick={handleSearch} className="search-btn">搜索</button>