react 项目--博客系统 ( 22 )

Loading.....

接上篇文章,在完成了文章的创建后,接下来完成文章的获取(三种形式)、更新及删除;

老规矩上思路:

文章获取(单个文章):

  • 获取参数 : slug
  • 获取文章:根据slug获取文章及 关联的标签
  • 获取当前文章的作者信息 : userEmail
  • 返回数据处理: 标签和作者信息
  • 响应数据

 文章获取(已关注作者的文章):

  • 获取登录用户
  • 获取当前登录用户关注的作者
  • 判断获取文章是否为空
  • 获取作者email
  • 获取作者文章
  • 作者信息-文章-标签处理
  • 响应数据

文章获取(全局文章):

  • 获取条件参数
  • 获取文章数组
    • 按标签查询

    • 按作者查询

    • 按标签和作者查询

    • 剩余情况

  • 文章数据处理
  • 响应数据

在有了思路后,我们开始按照思路逐步实现;(详细代码内容在文章底部

在控制器中的 articles.js 中先声明两个函数方法,用来进行文章优化(优化作者和标签信息);

 

 先实现单个文章的获取:

 再实现已关注作者文章的获取:

 下一步再实现全局文章的获取:

测试:

完成之后在终端启动服务,我们利用 postman 及 Navicat 进行测试;

首先在 postman 中创建三个测试获取数据的接口;

 get article 用来测试单个文章的获取;

 get follow articles 用来测试已关注作者的所有文章;

 最后 get articles 用来测试全局文章的获取;

利用  Navicat 可以查看我们创建的文章数据及相应关系表;

详细代码:

articles.js:

const HttpException = require("../exceptions/http_expetion");
const { validateCreateArticle } = require("../utils/validate/article_validate");
const Article = require("../models/article");
const User = require("../models/user");
const { getSlug } = require("../utils/slug");
const Tag = require("../models/tag");
const sequelize = require("../db/sequelize");

//单个文章优化(标签优化、作者优化)
function handleArticle(article, author) {
  const newTags = []
  for (const i of article.dataValues.tags) {
    newTags.push(i.name)
  }
  article.dataValues.tags = newTags

  //作者优化
  delete author.dataValues.password
  delete author.dataValues.email
  article.dataValues.author = author

  return article.dataValues
}

//多个文章优化(标签优化、作者优化)
function handleArticles(article) {
  // 标签优化
  const newTags = []
  for (const i of article.dataValues.tags) {
    newTags.push(i.name)
  }
  article.dataValues.tags = newTags
  
  //作者优化
  let { username, email , bio, avatar} = article.dataValues.user 
  let author = {
    username,
    email,
    bio,
    avatar
  }
  delete article.dataValues.user
  article.dataValues.author = author
  
  return article.dataValues
}

//创建文章
module.exports.createArticle = async (req, res, next) => {
  try {
    //获取请求数据
    const { title, description, body, tags } = req.body.article
    //获取内容验证
    let { error, validate } = validateCreateArticle(title, description, body)
    if (!validate) {
      throw new HttpException(401, '文章内容不存在!!!', error)
    }
    //获取作者信息
    const { email } = req.user
    const author = await User.findByPk(email)
    if (!author) {
      throw new HttpException(401, '作者账号不存在!!!', 'author is not found!!!')
    }
    //创建文章
    //  生成文章别名
    let slug = getSlug()
    //  存储数据:
    let article = await Article.create({
      slug,
      title,
      description,
      body,
      userEmail: author.email
    })
    //存储文章和标签的处理
    //  自定义
    //  数据库已有
    if (tags) {
      for (const i of tags) {
        let existTag = await Tag.findByPk(i)
        let newTag
        if (!existTag) {
          newTag = await Tag.create({ name: i })
          await article.addTag(newTag)
        } else {
          await article.addTag(existTag)
        }
      }
    }

    //返回数据 (文章、标签、作者)
    article = await Article.findByPk(slug, { include: Tag }) //追加标签

    //标签优化

    //作者优化

    article = handleArticle(article, author) //文章优化抽离

    res.status(201)
      .json({
        status: 1,
        message: '创建文章成功!!!',
        data: article
      })
  } catch (err) {
    next(err);
  }
};


//获取文章:获取单个
module.exports.getArticle = async (req, res, next) => {
  try {
    //获取参数:文章别名slug(文章唯一标识符)
    const { slug } = req.params
    //获取信息:根据slug获取文章相关信息
    let article = await Article.findByPk(slug, { include: Tag })
    //获取作者信息
    const author = await article.getUser()
    //返回数据处理
    article = handleArticle(article, author)
    //返回响应数据
    res.status(200)
      .json({
        status: 1,
        message: '获取单个文章成功!!!',
        data: article
      })

  } catch (err) {
    next(err);
  }
};


//获取文章:获取已关注作者的文章
module.exports.getFollowArticle = async (req, res, next) => {
  try {
    //获取登录用户
    const fansEmail = req.user.email
    //获取当前登录用户关注的作者
    const query = `SELECT userEmail FROM followers WHERE followerEmail="${fansEmail}"`
    const followAuthors = await sequelize.query(query)
    //判断获取文章是否为空
    if (followAuthors[0].length == 0) {
      return res.status(200)
        .json({
          status: 1,
          message: '当前用户没有关注的作者--获取文章为空!!!',
          data: []
        })
    }
    //获取作者email
    let followAuthorEmails = []
    for (const i of followAuthors[0]) {
      followAuthorEmails.push(i.userEmail)
    }
    //获取作者文章
    let articleAll = await Article.findAll({
      where: {
        UserEmail: followAuthorEmails
      },
      include: [Tag, User]
    })
    //作者信息-文章-标签处理
    let articles = []
    for (const i of articleAll) {
      articles.push(handleArticles(i))
    }
    //响应数据
    res.status(200)
      .json({
        status: 1,
        message: '已关注作者的文章获取成功!!!',
        data: articles
      })

  } catch (err) {
    next(err);
  }
};


//获取文章:获取全局文章
module.exports.getArticles = async (req, res, next) => {
  try {
    //获取条件参数
    const {tag,author,limit=20,offset=0} = req.query
    //获取文章数组
    let articleAll = []

    if(tag&&!author){  //按标签查询
      articleAll = await Article.findAll({
        include:[{
          model:Tag,
          attributes:['name'],
          where:{name:tag}
        },{
          model:User,
          attributes:['email','username','bio','avatar']
        }],
        limit:parseInt(limit),
        offset:parseInt(offset)
      })
    }else if(!tag&&author){  //按作者查询
      articleAll = await Article.findAll({
        include:[{
          model:Tag,
          attributes:['name']
        },{
          model:User,
          attributes:['email','username','bio','avatar'],
          where:{name:author}
        }],
        limit:parseInt(limit),
        offset:parseInt(offset)
      })
    }else if(tag&&author){  //按标签和作者查询
      articleAll = await Article.findAll({
        include:[{
          model:Tag,
          attributes:['name'],
          where:{name:tag}
        },{
          model:User,
          attributes:['email','username','bio','avatar'],
          where:{name:author}
        }],
        limit:parseInt(limit),
        offset:parseInt(offset)
      })
    }else{ //剩余情况
      articleAll = await Article.findAll({
        include:[{
          model:Tag,
          attributes:['name'],
        },{
          model:User,
          attributes:['email','username','bio','avatar']
        }],
        limit:parseInt(limit),
        offset:parseInt(offset)
      })
    }

    //文章数据处理
    let articles = []
    for (const i of articleAll) {
      articles.push(handleArticles(i))
    }
    //响应数据
    res.status(200)
      .json({
        status: 1,
        message: '文章获取成功!!!',
        data: articles
      })

  } catch (err) {
    next(err);
  }
};

未完待续......

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值