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

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

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

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

Change-Id: If822351183e9d55a5a56ff5cf1e13b313fdbe231
diff --git a/mock/post.ts b/mock/post.ts
new file mode 100644
index 0000000..fdbb9f3
--- /dev/null
+++ b/mock/post.ts
@@ -0,0 +1,290 @@
+import { Request, Response } from 'express';
+
+// Mock数据
+const mockPosts = [
+  {
+    postId: 1,
+    title: '【日剧推荐】献给刚刚接触日剧的你',
+    content: `
+      <div class="post-content">
+        <p>在日本,并没有四大台柱的称谓,这一说法的由来是贴吧的一个投票。</p>
+        <h3>校园剧</h3>
+        <p>龙樱 - 校园青春励志剧,如果你还没参加高考,推荐你提前看看,相信你会有所收获。</p>
+        <p>野猪大改造 - 两个J家美少年和两个台柱,除第一集节奏稍慢外,无硬伤,有友情有效笑有泪水。</p>
+        <h3>职场剧</h3>
+        <p>麻辣教师 - 小栗旬还是个弱小男生。</p>
+        <p>极道鲜师 - 学生上课搞乱不听讲怎么办,小栗来教你。</p>
+      </div>
+    `,
+    summary: '这是一篇关于日剧推荐的帖子,包含了校园剧和职场剧的推荐。',
+    coverImage: '/images/flower.jpg',
+    authorId: 1,
+    author: 'Ryo',
+    views: 87951,
+    comments: 15,
+    favorites: 256,
+    likes: 1024,
+    status: '1',
+    publishTime: '2017年8月26日',
+    tags: '日剧,嘉宾专栏,作品合集',
+    promotionPlanId: 1,
+    createTime: '2017-08-26 10:30:00',
+    updateTime: '2017-08-26 10:30:00',
+  },
+  {
+    postId: 2,
+    title: '【2025年4月档】对岸的家务事 高清1080P 新番双语+中文字幕 百度网盘 更新07',
+    content: '<p>对岸的家务事是一部关于家庭生活的日剧。</p>',
+    summary: '对岸的家务事是一部关于家庭生活的日剧。',
+    coverImage: '/images/flower.jpg',
+    authorId: 2,
+    author: '日剧翻译组',
+    views: 3245,
+    comments: 156,
+    favorites: 89,
+    likes: 345,
+    status: '1',
+    publishTime: '2025-5-14',
+    tags: '日剧,2025,家务',
+    promotionPlanId: null,
+    createTime: '2025-05-14 10:30:00',
+    updateTime: '2025-05-14 10:30:00',
+  },
+  {
+    postId: 3,
+    title: '【2025年4月档】天久鹰央的推理历表 高清1080P 中文字幕 百度网盘 更新04',
+    content: '<p>天久鹰央的推理历表是一部推理题材的日剧。</p>',
+    summary: '天久鹰央的推理历表是一部推理题材的日剧。',
+    coverImage: '/images/flower.jpg',
+    authorId: 2,
+    author: '日剧翻译组',
+    views: 4589,
+    comments: 267,
+    favorites: 123,
+    likes: 567,
+    status: '1',
+    publishTime: '2025-5-14',
+    tags: '日剧,2025,推理',
+    promotionPlanId: null,
+    createTime: '2025-05-14 10:30:00',
+    updateTime: '2025-05-14 10:30:00',
+  }
+];
+
+const mockComments = [
+  {
+    commentId: 1,
+    postId: 1,
+    content: '早期的堀北真希真是太美了',
+    userId: 10,
+    userName: 'Inchou',
+    userAvatar: 'https://via.placeholder.com/40',
+    parentId: 0,
+    status: '1',
+    likes: 5,
+    createTime: '2025-05-15 05:19:00',
+  },
+  {
+    commentId: 2,
+    postId: 1,
+    content: '谢谢分享 😚',
+    userId: 11,
+    userName: '紫毛球',
+    userAvatar: 'https://via.placeholder.com/40',
+    parentId: 0,
+    status: '1',
+    likes: 3,
+    createTime: '2025-05-02 10:35:00',
+  },
+  {
+    commentId: 3,
+    postId: 1,
+    content: '感谢分享',
+    userId: 12,
+    userName: 'JJxMM666',
+    userAvatar: 'https://via.placeholder.com/40',
+    parentId: 0,
+    status: '1',
+    likes: 2,
+    createTime: '2025-05-01 18:54:00',
+  }
+];
+
+export default {
+  // 获取帖子列表
+  'GET /api/post/list': (req: Request, res: Response) => {
+    const { pageNum = 1, pageSize = 10, title, status = '1' } = req.query;
+    
+    let filteredPosts = mockPosts.filter(post => post.status === status);
+    
+    if (title) {
+      filteredPosts = filteredPosts.filter(post => 
+        post.title.toLowerCase().includes((title as string).toLowerCase())
+      );
+    }
+
+    const startIndex = (Number(pageNum) - 1) * Number(pageSize);
+    const endIndex = startIndex + Number(pageSize);
+    const paginatedPosts = filteredPosts.slice(startIndex, endIndex);
+
+    res.json({
+      code: 200,
+      rows: paginatedPosts,
+      total: filteredPosts.length,
+      msg: '查询成功',
+    });
+  },
+
+  // 获取帖子详情
+  'GET /api/post/:id': (req: Request, res: Response) => {
+    const { id } = req.params;
+    const post = mockPosts.find(p => p.postId === Number(id));
+    
+    if (!post) {
+      return res.json({
+        code: 404,
+        msg: '帖子不存在',
+      });
+    }
+
+    const postComments = mockComments
+      .filter(c => c.postId === Number(id) && c.parentId === 0)
+      .map(comment => ({
+        comment,
+        replies: mockComments.filter(c => c.parentId === comment.commentId)
+      }));
+
+    const authorPosts = mockPosts
+      .filter(p => p.authorId === post.authorId && p.postId !== post.postId)
+      .slice(0, 3);
+
+    const similarPosts = mockPosts
+      .filter(p => {
+        if (p.postId === post.postId) return false;
+        const postTags = post.tags.split(',');
+        const pTags = p.tags.split(',');
+        return postTags.some(tag => pTags.includes(tag));
+      })
+      .slice(0, 3);
+
+    res.json({
+      code: 200,
+      data: {
+        post,
+        tags: post.tags.split(',').map((tag, index) => ({
+          tagId: index + 1,
+          tagName: tag,
+          tagColor: 'blue',
+          postCount: Math.floor(Math.random() * 100) + 1,
+          status: '0'
+        })),
+        comments: postComments,
+        authorPosts,
+        similarPosts,
+        favorited: false
+      },
+      msg: '查询成功',
+    });
+  },
+
+  // 添加评论
+  'POST /api/post/comment': (req: Request, res: Response) => {
+    const { postId, content, parentId = 0 } = req.body;
+    
+    if (!postId || !content) {
+      return res.json({
+        code: 400,
+        msg: '参数不完整',
+      });
+    }
+
+    const newComment = {
+      commentId: Date.now(),
+      postId: Number(postId),
+      content,
+      userId: 100,
+      userName: '当前用户',
+      userAvatar: 'https://via.placeholder.com/40',
+      parentId: Number(parentId),
+      status: '1',
+      likes: 0,
+      createTime: new Date().toLocaleString('zh-CN'),
+    };
+
+    mockComments.push(newComment);
+
+    // 更新帖子评论数
+    const post = mockPosts.find(p => p.postId === Number(postId));
+    if (post) {
+      post.comments += 1;
+    }
+
+    res.json({
+      code: 200,
+      data: newComment,
+      msg: '评论成功',
+    });
+  },
+
+  // 收藏/取消收藏帖子
+  'POST /api/post/favorite/:id': (req: Request, res: Response) => {
+    const { id } = req.params;
+    const { favorite } = req.query;
+    
+    const post = mockPosts.find(p => p.postId === Number(id));
+    if (!post) {
+      return res.json({
+        code: 404,
+        msg: '帖子不存在',
+      });
+    }
+
+    if (favorite === 'true') {
+      post.favorites += 1;
+      res.json({
+        code: 200,
+        msg: '收藏成功',
+      });
+    } else {
+      post.favorites = Math.max(0, post.favorites - 1);
+      res.json({
+        code: 200,
+        msg: '取消收藏成功',
+      });
+    }
+  },
+
+  // 获取热门标签
+  'GET /api/post/tags/hot': (req: Request, res: Response) => {
+    const mockTags = [
+      { tagId: 1, tagName: '日剧', tagColor: 'blue', postCount: 150, status: '0' },
+      { tagId: 2, tagName: '电影', tagColor: 'green', postCount: 120, status: '0' },
+      { tagId: 3, tagName: '音乐', tagColor: 'orange', postCount: 80, status: '0' },
+      { tagId: 4, tagName: '推理', tagColor: 'purple', postCount: 65, status: '0' },
+      { tagId: 5, tagName: '爱情', tagColor: 'pink', postCount: 45, status: '0' },
+    ];
+
+    res.json({
+      code: 200,
+      data: mockTags,
+      msg: '查询成功',
+    });
+  },
+
+  // 根据标签获取帖子
+  'GET /api/post/bytag/:tagId': (req: Request, res: Response) => {
+    const { tagId } = req.params;
+    
+    // 简单的mock实现,实际应该根据tagId查询相关帖子
+    const filteredPosts = mockPosts.filter(post => 
+      post.tags.includes('日剧') // 假设查询日剧标签
+    );
+
+    res.json({
+      code: 200,
+      rows: filteredPosts,
+      total: filteredPosts.length,
+      msg: '查询成功',
+    });
+  },
+}; 
\ No newline at end of file