next.js搭建博客系统-10-发布评论

435 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

文章系列:

next.js搭建博客系统-01-环境搭建

next.js搭建博客系统-02-实现Layout布局

next.js搭建博客系统-03-登录组件(登录弹窗)

next.js搭建博客系统-04-登录模块(验证码和登录)

next.js搭建博客系统-05-数据库操作

next.js搭建博客系统-06-发布文章(1)

next.js搭建博客系统-07-发布文章(2)

next.js搭建博客系统-08-ssr渲染首页文章列表

next.js搭建博客系统-09-ssr渲染文章详情页

next.js搭建博客系统-10-发布评论

next.js搭建博客系统-11-标签管理(1)

next.js搭建博客系统-12-标签管理(2)

评论页面

首先 先编写 发布评论 和评论列表的页面

只有登录的用户才能发布评论,所以这里有个判断,判断只有获取到用户的信息,才显示 发布评论的 按钮

const store = useStore();
const loginUserInfo = store?.user?.userInfo;



{loginUserInfo?.userId && (
            <div className={styles.enter}>
              <Avatar src={avatar} size={40} />
              <div className={styles.content}>
                <Input.TextArea
                  placeholder="请输入评论"
                  rows={4}
                  value={inputVal}
                  onChange={(event) => setInputVal(event?.target?.value)}
                />
                <Button type="primary" onClick={handleComment}>
                  发表评论
                </Button>
              </div>
            </div>
          )}

然后 获取 所有的 评论 列表,渲染到页面上

<div className={styles.display}>
            {comments?.map((comment: any) => (
              <div className={styles.wrapper} key={comment?.id}>
                <Avatar src={comment?.user?.avatar} size={40} />
                <div className={styles.info}>
                  <div className={styles.name}>
                    <div>{comment?.user?.nickname}</div>
                    <div className={styles.date}>
                      {format(
                        new Date(comment?.update_time),
                        'yyyy-MM-dd hh:mm:ss'
                      )}
                    </div>
                  </div>
                  <div className={styles.content}>{comment?.content}</div>
                </div>
              </div>
            ))}
          </div>

这里 有 两个逻辑接口,一个是 发布评论的接口,一个是 获取所有评论数据的接口

发布评论接口

首先 编写 发布评论的接口

1.首先获取 参数,一个参数是文章的id,一个是评论的内容

2.将这两个参数 传给 发布评论的接口

post('/api/comment/publish', {
        articleId: article?.id,
        content: inputVal,
      })

3.接下来 看下 发布评论的接口

4.新建 pages/api/comment/publish.ts

5.引入 数据库 和 session的配置

import { NextApiRequest, NextApiResponse } from 'next';
import { withIronSessionApiRoute } from 'iron-session/next';
import { ironOptions } from 'config/index';
import { ISession } from 'pages/api/index';
import { prepareConnection } from 'db/index';
import { User, Article, Comment } from 'db/entity/index';
import { EXCEPTION_COMMENT } from 'pages/api/config/codes';

6.通过 传过来的参数 获取 文章id 和 评论的内容

const { articleId = 0, content = '' } = req.body;

7.链接 评论接口的 数据库

 const db = await prepareConnection();
  const commentRepo = db.getRepository(Comment);

  const comment = new Comment();

8.实例化 Comment类,根据 session信息,从users表中查询 当前用户,根据文章id,查询文章信息,将这些信息全部添加到 comment实例中,保存到 comment表中

  const comment = new Comment();
  comment.content = content;
  comment.create_time = new Date();
  comment.update_time = new Date();

  const user = await db.getRepository(User).findOne({
    id: session?.userId,
  });

  const article = await db.getRepository(Article).findOne({
    id: articleId,
  });

  if (user) {
    comment.user = user;
  }
  if (article) {
    comment.article = article;
  }

  const resComment = await commentRepo.save(comment);

9.如果保存成功,则提示发布成功,否则提示发布失败

if (resComment) {
    res.status(200).json({
      code: 0,
      msg: '发表成功',
      data: resComment,
    });
  } else {
    res.status(200).json({
      ...EXCEPTION_COMMENT.PUBLISH_FAILED,
    });
  }

10.当调用发布接口成功的时候,提示发布成功,并且将新发布的评论 添加到 评论列表中,显示在评论中。同时把评论框的内容清空。注意这个将 新发布的评论 添加到 评论列表的时候,使用react的不可变原则,使用concat方法。

request
      .post('/api/comment/publish', {
        articleId: article?.id,
        content: inputVal,
      })
      .then((res: any) => {
        if (res?.code === 0) {
          message.success('发表成功');
          const newComments = [
            {
              id: Math.random(),
              create_time: new Date(),
              update_time: new Date(),
              content: inputVal,
              user: {
                avatar: loginUserInfo?.avatar,
                nickname: loginUserInfo?.nickname,
              },
            },
          ].concat([...(comments as any)]);
          setComments(newComments);
          setInputVal('');
        } else {
          message.error('发表失败');
        }
      });

11.最后拿到最新的 评论列表,将评论列表 遍历 渲染到页面上

<div className={styles.display}>
            {comments?.map((comment: any) => (
              <div className={styles.wrapper} key={comment?.id}>
                <Avatar src={comment?.user?.avatar} size={40} />
                <div className={styles.info}>
                  <div className={styles.name}>
                    <div>{comment?.user?.nickname}</div>
                    <div className={styles.date}>
                      {format(
                        new Date(comment?.update_time),
                        'yyyy-MM-dd hh:mm:ss'
                      )}
                    </div>
                  </div>
                  <div className={styles.content}>{comment?.content}</div>
                </div>
              </div>
            ))}
          </div>