创作中心模块包含首页展示、个人中心、帖子审核。

“首页展示”支持广告轮播展示、推广帖子优先展示、分页显示所有帖子、导航栏便捷标签筛选帖子、全局标题模糊搜索帖子、点击帖子“查看更多”进入帖子详情页。帖子详情页展示帖子封面图片、作者时间、详细内容(可以插入种子链接对种子进行介绍与推广)等基本信息、对帖子点赞收藏举报评论回复、查看相关推荐帖子。相关推荐会推荐当前帖子作者的其他帖子(最多推荐5篇),还会推荐具有相似标签的其他帖子,两者总共最多推荐9篇帖子。

“个人中心”包含“我的中心”和“我的收藏”。
“我的中心”中可以管理已经成功发布的帖子(编辑、删除帖子),还可以发布新帖子。发布新帖子时除了填写帖子基本信息以外,帖子标签支持下拉多项选择,用户还可以选择帖子推广项目并进行支付。设置了多种推广项目,包含广告轮播推广、帖子置顶展示、限时优先展示、分类页首条展示。系统后台执行自动定时任务,每小时对帖子的推广时效性进行检查,如超出推广时限,则取消帖子的推广显示特权。用户点击发布帖子后帖子处于待审核状态,需要管理员审核通过才能正常发布在首页展示页面。编辑帖子时用户可以追加帖子推广,但如果帖子处于推广状态,则禁止修改推广项目。
“我的收藏”中可以便捷查看所有已收藏的帖子。

“帖子审核”包含“帖子发布管理”和“帖子举报管理”。“帖子审核”板块具有权限管理,只有管理员界面能够进入。
“帖子发布管理”对所有待审核帖子进行处理,支持预览待审核帖子详细内容,批准通过和拒绝通过选项。
“帖子举报管理”对所有用户的举报请求进行人工审核,如果举报内容属实,则将帖子下架处理,如果举报内容不属实,驳回举报请求。所有举报请求的处理结果均留存显示,方便后续再次审查。

Change-Id: If822351183e9d55a5a56ff5cf1e13b313fdbe231
diff --git a/src/pages/UserCenter/index.tsx b/src/pages/UserCenter/index.tsx
new file mode 100644
index 0000000..13de6ad
--- /dev/null
+++ b/src/pages/UserCenter/index.tsx
@@ -0,0 +1,968 @@
+import React, { useState, useEffect } from 'react';
+import { 
+  Card, 
+  Tabs, 
+  Button, 
+  Table, 
+  Modal, 
+  Form, 
+  Input, 
+  Select, 
+  Upload, 
+  message, 
+  Tag, 
+  Space,
+  Popconfirm,
+  Row,
+  Col,
+  Radio,
+  InputNumber,
+  Image
+} from 'antd';
+import { 
+  PlusOutlined, 
+  EditOutlined, 
+  DeleteOutlined, 
+  EyeOutlined,
+  UploadOutlined,
+  HeartOutlined,
+  LoadingOutlined
+} from '@ant-design/icons';
+import { useNavigate } from 'react-router-dom';
+import { 
+  getMyPosts, 
+  getMyFavorites, 
+  publishPost, 
+  updatePost, 
+  deletePost,
+  getAvailableTags,
+  uploadImage,
+  deleteImage,
+  getPromotionPlans,
+  createPayment,
+  getPromotionStatus,
+  confirmPayment,
+  cancelPayment
+} from '@/services/post';
+import PostCard from '../PostCenter/PostCard';
+import styles from './index.module.css';
+
+const { TabPane } = Tabs;
+const { TextArea } = Input;
+const { Option } = Select;
+
+interface PostFormData {
+  title: string;
+  content: string;
+  summary: string;
+  tags: string[] | string;
+  promotionPlan?: number;
+  coverImage?: string;
+}
+
+interface PromotionPlan {
+  id: number;
+  name: string;
+  description: string;
+  price: number;
+  duration: number;
+}
+
+interface PaymentRecord {
+  paymentId: number;
+  postId: number;
+  planId: number;
+  userId: number;
+  amount: number;
+  paymentStatus: string;
+  paymentTime: string;
+}
+
+const UserCenter: React.FC = () => {
+  const navigate = useNavigate();
+  const [activeTab, setActiveTab] = useState('myPosts');
+  const [publishModalVisible, setPublishModalVisible] = useState(false);
+  const [editModalVisible, setEditModalVisible] = useState(false);
+  const [paymentModalVisible, setPaymentModalVisible] = useState(false);
+  const [myPosts, setMyPosts] = useState<API.Post.PostInfo[]>([]);
+  const [favorites, setFavorites] = useState<API.Post.PostInfo[]>([]);
+  const [loading, setLoading] = useState(false);
+  const [form] = Form.useForm();
+  const [editForm] = Form.useForm();
+  const [selectedPromotion, setSelectedPromotion] = useState<PromotionPlan | null>(null);
+  const [currentEditPost, setCurrentEditPost] = useState<API.Post.PostInfo | null>(null);
+  const [availableTags, setAvailableTags] = useState<API.Post.PostTag[]>([]);
+  const [promotionPlans, setPromotionPlans] = useState<PromotionPlan[]>([]);
+  const [uploadLoading, setUploadLoading] = useState(false);
+  const [editUploadLoading, setEditUploadLoading] = useState(false);
+  const [coverImageUrl, setCoverImageUrl] = useState<string>('');
+  const [editCoverImageUrl, setEditCoverImageUrl] = useState<string>('');
+  const [currentPayment, setCurrentPayment] = useState<PaymentRecord | null>(null);
+  const [isEditingPromotion, setIsEditingPromotion] = useState(false);
+
+  useEffect(() => {
+    if (activeTab === 'myPosts') {
+      fetchMyPosts();
+    } else if (activeTab === 'favorites') {
+      fetchFavorites();
+    }
+  }, [activeTab]);
+
+  useEffect(() => {
+    fetchAvailableTags();
+    fetchPromotionPlans();
+  }, []);
+
+  const fetchMyPosts = async () => {
+    setLoading(true);
+    try {
+      const response = await getMyPosts({ pageNum: 1, pageSize: 100 });
+      if (response.code === 200) {
+        setMyPosts(response.rows || []);
+      } else {
+        message.error(response.msg || '获取我的帖子失败');
+      }
+    } catch (error) {
+      message.error('获取我的帖子失败');
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  const fetchFavorites = async () => {
+    setLoading(true);
+    try {
+      const response = await getMyFavorites({ pageNum: 1, pageSize: 100 });
+      if (response.code === 200) {
+        setFavorites(response.rows || []);
+      } else {
+        message.error(response.msg || '获取收藏列表失败');
+      }
+    } catch (error) {
+      message.error('获取收藏列表失败');
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  const fetchAvailableTags = async () => {
+    try {
+      const response = await getAvailableTags();
+      if (response.code === 200) {
+        setAvailableTags(response.data || []);
+      } else {
+        message.error(response.msg || '获取可用标签失败');
+      }
+    } catch (error) {
+      message.error('获取可用标签失败');
+    }
+  };
+
+  const fetchPromotionPlans = async () => {
+    try {
+      const response = await getPromotionPlans();
+      if (response.code === 200) {
+        setPromotionPlans(response.data || []);
+      }
+    } catch (error) {
+      console.error('获取推广计划失败:', error);
+    }
+  };
+
+  const handlePublishPost = async (values: PostFormData) => {
+    try {
+      if (values.promotionPlan && selectedPromotion) {
+        // 如果选择了推广,创建支付记录
+        const paymentResponse = await createPayment({
+          postId: 0, // 新帖子,暂时设为0,后端会处理
+          planId: selectedPromotion.id,
+          amount: selectedPromotion.price
+        });
+        
+        if (paymentResponse.code === 200) {
+          setCurrentPayment(paymentResponse.data);
+        setPaymentModalVisible(true);
+        return;
+        } else {
+          message.error(paymentResponse.msg || '创建支付记录失败');
+          return;
+        }
+      }
+      
+      // 直接发布帖子
+      await submitPost(values);
+    } catch (error) {
+      message.error('发布帖子失败');
+    }
+  };
+
+  const submitPost = async (values: PostFormData) => {
+    try {
+      // 处理标签格式
+      const tagsString = Array.isArray(values.tags) ? values.tags.join(',') : values.tags;
+      
+      const postData = {
+        title: values.title,
+        content: values.content,
+        summary: values.summary,
+        tags: tagsString,
+        promotionPlan: values.promotionPlan,
+        coverImage: coverImageUrl || undefined
+      };
+      
+      const response = await publishPost(postData);
+      if (response.code === 200) {
+        message.success('帖子发布成功');
+        setPublishModalVisible(false);
+        form.resetFields();
+        setSelectedPromotion(null);
+        setCoverImageUrl('');
+        fetchMyPosts();
+      } else {
+        message.error(response.msg || '发布帖子失败');
+      }
+    } catch (error) {
+      message.error('发布帖子失败');
+    }
+  };
+
+  const handleEditPost = async (post: API.Post.PostInfo) => {
+    setCurrentEditPost(post);
+    const tagsArray = post.tags ? (typeof post.tags === 'string' ? post.tags.split(',') : post.tags) : [];
+    
+    // 检查推广状态
+    try {
+      const promotionResponse = await getPromotionStatus(post.postId || post.id || 0);
+      if (promotionResponse.code === 200) {
+        const { hasPromotion, promotionPlanId } = promotionResponse.data;
+        setIsEditingPromotion(hasPromotion);
+        
+        editForm.setFieldsValue({
+          title: post.title,
+          content: post.content,
+          summary: post.summary,
+          tags: tagsArray,
+          promotionPlan: hasPromotion ? promotionPlanId : undefined
+        });
+      }
+    } catch (error) {
+      console.error('获取推广状态失败:', error);
+    editForm.setFieldsValue({
+      title: post.title,
+      content: post.content,
+      summary: post.summary,
+        tags: tagsArray,
+        promotionPlan: post.promotionPlanId
+    });
+    }
+    
+    setEditCoverImageUrl(post.coverImage || '');
+    setEditModalVisible(true);
+  };
+
+  const handleUpdatePost = async (values: any) => {
+    if (!currentEditPost) return;
+    
+    try {
+      // 处理标签格式
+      const tagsString = Array.isArray(values.tags) ? values.tags.join(',') : values.tags;
+      
+      // 检查是否选择了新的推广计划
+      const hasNewPromotion = values.promotionPlan && !isEditingPromotion;
+      
+      if (hasNewPromotion) {
+        // 如果选择了新的推广计划,需要先创建支付记录
+        const selectedPlan = promotionPlans.find(p => p.id === values.promotionPlan);
+        if (selectedPlan) {
+          setSelectedPromotion(selectedPlan);
+          
+          // 创建支付记录
+          const paymentResponse = await createPayment({
+            postId: currentEditPost.postId || currentEditPost.id || 0,
+            planId: selectedPlan.id,
+            amount: selectedPlan.price
+          });
+          
+          if (paymentResponse.code === 200) {
+            setCurrentPayment(paymentResponse.data);
+            setPaymentModalVisible(true);
+            return; // 等待支付完成后再更新帖子
+          } else {
+            message.error(paymentResponse.msg || '创建支付记录失败');
+            return;
+          }
+        }
+      }
+      
+      // 直接更新帖子(没有新推广或已有推广)
+      await updatePostDirectly(values, tagsString);
+    } catch (error) {
+      message.error('更新帖子失败');
+    }
+  };
+
+  const updatePostDirectly = async (values: any, tagsString: string) => {
+    if (!currentEditPost) return;
+    
+      const updateData = {
+        ...currentEditPost,
+      title: values.title,
+      content: values.content,
+      summary: values.summary,
+      tags: tagsString,
+      coverImage: editCoverImageUrl || currentEditPost.coverImage,
+      promotionPlanId: values.promotionPlan
+    };
+    
+      const response = await updatePost(updateData);
+      if (response.code === 200) {
+        message.success('帖子更新成功');
+        setEditModalVisible(false);
+        editForm.resetFields();
+        setCurrentEditPost(null);
+      setEditCoverImageUrl('');
+      setIsEditingPromotion(false);
+        fetchMyPosts();
+      } else {
+        message.error(response.msg || '更新帖子失败');
+    }
+  };
+
+  const handleDeletePost = async (postId: number) => {
+    try {
+      const response = await deletePost(postId);
+      if (response.code === 200) {
+        message.success('帖子删除成功');
+        fetchMyPosts();
+      } else {
+        message.error(response.msg || '删除帖子失败');
+      }
+    } catch (error) {
+      message.error('删除帖子失败');
+    }
+  };
+
+  const handleViewPost = (postId: number) => {
+    navigate(`/post-detail/${postId}`);
+  };
+
+  const handlePaymentConfirm = async () => {
+    if (!currentPayment) return;
+    
+    try {
+      const response = await confirmPayment(currentPayment.paymentId);
+      if (response.code === 200) {
+        message.success('支付成功,推广已生效');
+    setPaymentModalVisible(false);
+        setCurrentPayment(null);
+        
+        // 如果是编辑模式,完成帖子更新
+        if (editModalVisible && currentEditPost) {
+          const values = editForm.getFieldsValue();
+          const tagsString = Array.isArray(values.tags) ? values.tags.join(',') : values.tags;
+          await updatePostDirectly(values, tagsString);
+        } else {
+          // 如果是发布模式
+    setPublishModalVisible(false);
+    form.resetFields();
+    setSelectedPromotion(null);
+          setCoverImageUrl('');
+    fetchMyPosts();
+        }
+      } else {
+        message.error(response.msg || '支付确认失败');
+      }
+    } catch (error) {
+      message.error('支付确认失败');
+    }
+  };
+
+  const handlePaymentCancel = async () => {
+    if (!currentPayment) return;
+    
+    try {
+      await cancelPayment(currentPayment.paymentId);
+      message.info('支付已取消');
+      setPaymentModalVisible(false);
+      setCurrentPayment(null);
+      setSelectedPromotion(null);
+    } catch (error) {
+      console.error('取消支付失败:', error);
+      setPaymentModalVisible(false);
+      setCurrentPayment(null);
+      setSelectedPromotion(null);
+    }
+  };
+
+  const handleImageUpload = async (file: any) => {
+    setUploadLoading(true);
+    try {
+      const formData = new FormData();
+      formData.append('file', file);
+      
+      const response = await uploadImage(formData);
+      if (response.code === 200 && response.data) {
+        setCoverImageUrl(response.data.url);
+        message.success('图片上传成功');
+        return false; // 阻止自动上传
+      } else {
+        message.error(response.msg || '图片上传失败');
+      }
+    } catch (error) {
+      message.error('图片上传失败');
+    } finally {
+      setUploadLoading(false);
+    }
+    return false;
+  };
+
+  const handleDeleteImage = async () => {
+    if (coverImageUrl) {
+      try {
+        const filename = coverImageUrl.split('/').pop();
+        if (filename) {
+          await deleteImage(filename);
+        }
+        setCoverImageUrl('');
+        message.success('图片删除成功');
+      } catch (error) {
+        message.error('图片删除失败');
+      }
+    }
+  };
+
+  const handleCancelPublish = async () => {
+    // 如果有上传的图片但没有发布帖子,删除图片
+    if (coverImageUrl) {
+      try {
+        const filename = coverImageUrl.split('/').pop();
+        if (filename) {
+          await deleteImage(filename);
+        }
+      } catch (error) {
+        console.error('删除图片失败:', error);
+      }
+    }
+    
+    setPublishModalVisible(false);
+    form.resetFields();
+    setSelectedPromotion(null);
+    setCoverImageUrl('');
+  };
+
+  const uploadButton = (
+    <div>
+      {uploadLoading ? <LoadingOutlined /> : <PlusOutlined />}
+      <div style={{ marginTop: 8 }}>上传封面</div>
+    </div>
+  );
+
+  const handleEditImageUpload = async (file: any) => {
+    setEditUploadLoading(true);
+    try {
+      const formData = new FormData();
+      formData.append('file', file);
+      
+      const response = await uploadImage(formData);
+      if (response.code === 200 && response.data) {
+        // 如果有旧图片,删除它
+        if (editCoverImageUrl) {
+          const oldFilename = editCoverImageUrl.split('/').pop();
+          if (oldFilename) {
+            await deleteImage(oldFilename);
+          }
+        }
+        
+        setEditCoverImageUrl(response.data.url);
+        message.success('图片上传成功');
+        return false;
+      } else {
+        message.error(response.msg || '图片上传失败');
+      }
+    } catch (error) {
+      message.error('图片上传失败');
+    } finally {
+      setEditUploadLoading(false);
+    }
+    return false;
+  };
+
+  const handleDeleteEditImage = async () => {
+    if (editCoverImageUrl) {
+      try {
+        const filename = editCoverImageUrl.split('/').pop();
+        if (filename) {
+          await deleteImage(filename);
+        }
+        setEditCoverImageUrl('');
+        message.success('图片删除成功');
+      } catch (error) {
+        message.error('图片删除失败');
+      }
+    }
+  };
+
+  const editUploadButton = (
+    <div>
+      {editUploadLoading ? <LoadingOutlined /> : <PlusOutlined />}
+      <div style={{ marginTop: 8 }}>上传封面</div>
+    </div>
+  );
+
+  const myPostsColumns = [
+    {
+      title: '标题',
+      dataIndex: 'title',
+      key: 'title',
+      render: (text: string, record: API.Post.PostInfo) => (
+        <a onClick={() => handleViewPost(record.postId || record.id || 0)}>{text}</a>
+      ),
+    },
+    {
+      title: '状态',
+      dataIndex: 'status',
+      key: 'status',
+      render: (status: string) => {
+        const statusMap: Record<string, { color: string; text: string }> = {
+          '0': { color: 'orange', text: '待审核' },
+          '1': { color: 'green', text: '已发布' },
+          '2': { color: 'red', text: '已拒绝' },
+          '3': { color: 'gray', text: '已下架' }
+        };
+        const statusInfo = statusMap[status] || { color: 'gray', text: '未知' };
+        return <Tag color={statusInfo.color}>{statusInfo.text}</Tag>;
+      },
+    },
+    {
+      title: '浏览量',
+      dataIndex: 'views',
+      key: 'views',
+    },
+    {
+      title: '评论数',
+      dataIndex: 'comments',
+      key: 'comments',
+    },
+    {
+      title: '收藏数',
+      dataIndex: 'favorites',
+      key: 'favorites',
+    },
+    {
+      title: '点赞数',
+      dataIndex: 'likes',
+      key: 'likes',
+    },
+    {
+      title: '发布时间',
+      dataIndex: 'publishTime',
+      key: 'publishTime',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: API.Post.PostInfo) => (
+        <Space size="middle">
+          <Button 
+            type="link" 
+            icon={<EyeOutlined />} 
+            onClick={() => handleViewPost(record.postId || record.id || 0)}
+          >
+            查看
+          </Button>
+          <Button 
+            type="link" 
+            icon={<EditOutlined />} 
+            onClick={() => handleEditPost(record)}
+          >
+            编辑
+          </Button>
+          <Popconfirm
+            title="确定要删除这篇帖子吗?"
+            onConfirm={() => handleDeletePost(record.postId || record.id || 0)}
+            okText="确定"
+            cancelText="取消"
+          >
+            <Button type="link" danger icon={<DeleteOutlined />}>
+              删除
+            </Button>
+          </Popconfirm>
+        </Space>
+      ),
+    },
+  ];
+
+  return (
+    <div className={styles.userCenterContainer}>
+      <Card title="个人中心" className={styles.userCenterCard}>
+        <Tabs activeKey={activeTab} onChange={setActiveTab}>
+          <TabPane tab="我的帖子" key="myPosts">
+            <div className={styles.tabContent}>
+              <div className={styles.tabHeader}>
+                <Button 
+                  type="primary" 
+                  icon={<PlusOutlined />}
+                  onClick={() => setPublishModalVisible(true)}
+                >
+                  发布新帖子
+                </Button>
+              </div>
+              <Table
+                columns={myPostsColumns}
+                dataSource={myPosts}
+                loading={loading}
+                rowKey="id"
+                pagination={{
+                  pageSize: 10,
+                  showTotal: (total) => `共 ${total} 条记录`,
+                }}
+              />
+            </div>
+          </TabPane>
+          
+          <TabPane tab="我的收藏" key="favorites">
+            <div className={styles.tabContent}>
+              <Row gutter={[24, 24]}>
+                {favorites.map((post: any) => {
+                  // 确保post对象有正确的id字段
+                  const formattedPost = {
+                    ...post,
+                    id: post.postId || post.id,
+                    tags: post.tags ? (Array.isArray(post.tags) ? post.tags : post.tags.split(',')) : []
+                  };
+                  return (
+                    <Col xs={24} sm={12} md={8} key={formattedPost.id}>
+                      <PostCard post={formattedPost} />
+                  </Col>
+                  );
+                })}
+              </Row>
+              {favorites.length === 0 && !loading && (
+                <div className={styles.emptyState}>
+                  <HeartOutlined style={{ fontSize: 48, color: '#ccc' }} />
+                  <p>暂无收藏的帖子</p>
+                </div>
+              )}
+            </div>
+          </TabPane>
+        </Tabs>
+      </Card>
+
+      {/* 发布帖子弹窗 */}
+      <Modal
+        title="发布新帖子"
+        open={publishModalVisible}
+        onCancel={handleCancelPublish}
+        footer={null}
+        width={800}
+      >
+        <Form
+          form={form}
+          layout="vertical"
+          onFinish={handlePublishPost}
+        >
+          <Form.Item
+            name="title"
+            label="帖子标题"
+            rules={[{ required: true, message: '请输入帖子标题' }]}
+          >
+            <Input placeholder="请输入帖子标题" />
+          </Form.Item>
+          
+          <Form.Item
+            name="summary"
+            label="帖子摘要"
+            rules={[{ required: true, message: '请输入帖子摘要' }]}
+          >
+            <TextArea rows={3} placeholder="请输入帖子摘要" />
+          </Form.Item>
+          
+          <Form.Item
+            name="content"
+            label="帖子内容"
+            rules={[{ required: true, message: '请输入帖子内容' }]}
+          >
+            <TextArea rows={8} placeholder="请输入帖子内容" />
+          </Form.Item>
+          
+          <Form.Item
+            name="coverImage"
+            label="封面图片(可选)"
+          >
+            <Upload
+              listType="picture-card"
+              showUploadList={false}
+              beforeUpload={handleImageUpload}
+            >
+              {coverImageUrl ? (
+                <Image
+                  src={coverImageUrl}
+                  alt="封面"
+                  width="100%"
+                  height="100%"
+                  style={{ objectFit: 'cover' }}
+                />
+              ) : (
+                uploadButton
+              )}
+            </Upload>
+            {coverImageUrl && (
+              <Button 
+                type="link" 
+                onClick={handleDeleteImage}
+                style={{ padding: 0, marginTop: 8 }}
+              >
+                删除图片
+              </Button>
+            )}
+          </Form.Item>
+          
+          <Form.Item
+            name="tags"
+            label="标签"
+            rules={[{ required: true, message: '请选择标签' }]}
+          >
+            <Select
+              mode="multiple"
+              placeholder="请选择标签"
+              allowClear
+              style={{ width: '100%' }}
+            >
+              {availableTags.map(tag => (
+                <Select.Option key={tag.tagId} value={tag.tagName}>
+                  <Tag color={tag.tagColor}>{tag.tagName}</Tag>
+                </Select.Option>
+              ))}
+            </Select>
+          </Form.Item>
+          
+          <Form.Item
+            name="promotionPlan"
+            label="推广选项(可选)"
+          >
+            <Radio.Group>
+              <Space direction="vertical">
+                <Radio value={undefined}>不选择推广</Radio>
+                {promotionPlans.map(plan => (
+                  <Radio key={plan.id} value={plan.id}>
+                    <div>
+                      <strong>{plan.name}</strong> - ¥{plan.price} ({plan.duration}天)
+                      <br />
+                      <span style={{ color: '#666', fontSize: '12px' }}>
+                        {plan.description}
+                      </span>
+                    </div>
+                  </Radio>
+                ))}
+              </Space>
+            </Radio.Group>
+          </Form.Item>
+          
+          <Form.Item>
+            <Space>
+              <Button type="primary" htmlType="submit">
+                {selectedPromotion ? '选择支付方式' : '发布帖子'}
+              </Button>
+              <Button onClick={handleCancelPublish}>
+                取消
+              </Button>
+            </Space>
+          </Form.Item>
+        </Form>
+      </Modal>
+
+      {/* 编辑帖子弹窗 */}
+      <Modal
+        title="编辑帖子"
+        open={editModalVisible}
+        onCancel={() => {
+          setEditModalVisible(false);
+          editForm.resetFields();
+          setCurrentEditPost(null);
+          setEditCoverImageUrl('');
+          setIsEditingPromotion(false);
+        }}
+        footer={null}
+        width={800}
+      >
+        <Form
+          form={editForm}
+          layout="vertical"
+          onFinish={handleUpdatePost}
+        >
+          <Form.Item
+            name="title"
+            label="帖子标题"
+            rules={[{ required: true, message: '请输入帖子标题' }]}
+          >
+            <Input placeholder="请输入帖子标题" />
+          </Form.Item>
+          
+          <Form.Item
+            name="summary"
+            label="帖子摘要"
+            rules={[{ required: true, message: '请输入帖子摘要' }]}
+          >
+            <TextArea rows={3} placeholder="请输入帖子摘要" />
+          </Form.Item>
+          
+          <Form.Item
+            name="content"
+            label="帖子内容"
+            rules={[{ required: true, message: '请输入帖子内容' }]}
+          >
+            <TextArea rows={8} placeholder="请输入帖子内容" />
+          </Form.Item>
+          
+          <Form.Item
+            name="coverImage"
+            label="封面图片"
+          >
+            <Upload
+              listType="picture-card"
+              showUploadList={false}
+              beforeUpload={handleEditImageUpload}
+            >
+              {editCoverImageUrl ? (
+                <Image
+                  src={editCoverImageUrl}
+                  alt="封面"
+                  width="100%"
+                  height="100%"
+                  style={{ objectFit: 'cover' }}
+                />
+              ) : (
+                editUploadButton
+              )}
+            </Upload>
+            {editCoverImageUrl && (
+              <Button 
+                type="link" 
+                onClick={handleDeleteEditImage}
+                style={{ padding: 0, marginTop: 8 }}
+              >
+                删除图片
+              </Button>
+            )}
+          </Form.Item>
+          
+          <Form.Item
+            name="tags"
+            label="标签"
+            rules={[{ required: true, message: '请选择标签' }]}
+          >
+            <Select
+              mode="multiple"
+              placeholder="请选择标签"
+              allowClear
+              style={{ width: '100%' }}
+            >
+              {availableTags.map(tag => (
+                <Select.Option key={tag.tagId} value={tag.tagName}>
+                  <Tag color={tag.tagColor}>{tag.tagName}</Tag>
+                </Select.Option>
+              ))}
+            </Select>
+          </Form.Item>
+          
+          <Form.Item
+            name="promotionPlan"
+            label="推广选项(可选)"
+          >
+            <Radio.Group disabled={isEditingPromotion}>
+              <Space direction="vertical">
+                <Radio value={undefined}>不选择推广</Radio>
+                {isEditingPromotion && (
+                  <div style={{ color: '#ff4d4f', fontSize: '12px', marginBottom: 8 }}>
+                    该帖子已购买推广,无法更改推广选项
+                  </div>
+                )}
+                {promotionPlans.map(plan => (
+                  <Radio key={plan.id} value={plan.id} disabled={isEditingPromotion}>
+                    <div>
+                      <strong>{plan.name}</strong> - ¥{plan.price} ({plan.duration}天)
+                      <br />
+                      <span style={{ color: '#666', fontSize: '12px' }}>
+                        {plan.description}
+                      </span>
+                    </div>
+                  </Radio>
+                ))}
+              </Space>
+            </Radio.Group>
+          </Form.Item>
+          
+          <Form.Item>
+            <Space>
+              <Button type="primary" htmlType="submit">
+                更新帖子
+              </Button>
+              <Button onClick={() => {
+                setEditModalVisible(false);
+                editForm.resetFields();
+                setCurrentEditPost(null);
+                setEditCoverImageUrl('');
+                setIsEditingPromotion(false);
+              }}>
+                取消
+              </Button>
+            </Space>
+          </Form.Item>
+        </Form>
+      </Modal>
+
+      {/* 支付弹窗 */}
+      <Modal
+        title="支付推广费用"
+        open={paymentModalVisible}
+        onCancel={handlePaymentCancel}
+        footer={null}
+        width={400}
+      >
+        <div className={styles.paymentModal}>
+          {selectedPromotion && (
+            <>
+              <div className={styles.paymentInfo}>
+                <h3>{selectedPromotion.name}</h3>
+                <p>{selectedPromotion.description}</p>
+                <p>费用: <strong>¥{selectedPromotion.price}</strong></p>
+                <p>时长: {selectedPromotion.duration}天</p>
+              </div>
+              
+              <div className={styles.qrCode}>
+                <div className={styles.qrCodePlaceholder}>
+                  <p>支付二维码</p>
+                  <p style={{ fontSize: '12px', color: '#666' }}>
+                    请使用支付宝扫描二维码支付
+                  </p>
+                  <div className={styles.mockQrCode}>
+                    <p>模拟二维码</p>
+                    <p>¥{selectedPromotion.price}</p>
+                  </div>
+                </div>
+              </div>
+              
+              <div className={styles.paymentActions}>
+                <Button 
+                  type="primary" 
+                  onClick={handlePaymentConfirm}
+                  style={{ width: '100%', marginBottom: 8 }}
+                >
+                  我已完成支付
+                </Button>
+                <Button 
+                  onClick={handlePaymentCancel}
+                  style={{ width: '100%' }}
+                >
+                  取消支付
+                </Button>
+              </div>
+            </>
+          )}
+        </div>
+      </Modal>
+    </div>
+  );
+};
+
+export default UserCenter; 
\ No newline at end of file