vue个人博客开发记录-文件上传&vue-quil-editor&mongo多层查询(二)

1.创建管理员

在这里插入图片描述

1.1 文件上传处理

  • express 本身是获取不到文件上传的数据,所以需要一个中间件来专门处理中间件 multer
  • multer({dest: './uploadImages'})表示将上传的图片传输到指定文件夹(这里以uploadImages为例,如果没有该文件夹,会自动生成),如果不添加dest属性,这些文件将保存在内存中,永远不会写入磁盘
const multer = require('multer')
const path = require('path')
  //  路径开头的/不会影响拼接
  // ..代表上一级文件 
  //'../../uploads' 也可以表示为 '..','..','uploads'
  const uploadPath = path.join(__dirname, '../../uploads')
  const upload = multer({ dest: uploadPath })
  //upload.single('key值'):当传递单个文件的时候,对文件的解析
  app.post('/admin/api/upload', upload.single('file'), (req, res) => {
    // req.file 是 `file` 文件的信息
    const file = req.file
    console.log(uploadPath);
    // file.url为服务器地址
    file.url = `http://localhost:3000/uploads/${file.filename}`
    res.send(file)
  })

1.2 数据库存密码处理,不能明文保存,使用散列存储bcryptjs

const mongoose = require('mongoose')
const admin = mongoose.Schema({
  username:{type:String},
  password:{
    type:String,
    select:false,//这个属性不会被查询出来
    set(value) {
      //密码做散列,不明文保存
      // 对密码进行加密
      // 1. 要进行加密的明文
      // 2. 随机字符串
      // 返回值是加密后的密码
      return require('bcryptjs').hashSync(value,12)
    }
  }
})
const AdminUser = mongoose.model('AdminUser',admin)
module.exports = AdminUser

1.3 登录接口处理

  • 当用户登录时,校验登录名和密码,然后返回一个token
const jwt = require('jsonwebtoken')
const assert = require('http-assert')
const AdminUser = require('../../models/AdminUser')
app.post('/admin/api/login',async (req,res)=>{
    //校验登录名和密码,然后返回一个token
    const { username , password } = req.body
    //1.根据用户名找用户
    const user = await AdminUser.findOne({username}).select('+password')
    //确保用户存在,如果不存在抛出422状态码并返回错误信息
    assert(user,422,'用户不存在')
    // 2.校验密码,与之前的暗文相比较
    const isValid = require('bcryptjs').compareSync(password,user.password)
    assert(isValid,422,'密码错误')
    // 3.返回token
    const token = jwt.sign({id:user._id},app.get('secret'))
    res.send({token})
  })

1.4 客户端进行路由限制

//meta属性添加在公开访问的路由中
{path: '/login',component: Login,meta:{isPublic:true}}

router.beforeEach((to,from,next)=>{
  console.log(to.meta)
  //如果不是公开访问的页面且页面的token不存在
  if(!to.meta.isPublic && !localStorage.getItem('token')){
    return next('/login')
  }
  next()
})

1.5 上传文件的登录校验

  • 使用vue的mixin
const auth = {
  methods:{
    getAuthHeaders(){
      return {Authorization:`Bear ${localStorage.getItem('token') || ''}`}
    }
  }
}
export default auth
  • 在需要上传的组件中使用
			<el-upload
              class="avatar-uploader"
              :action="$http.defaults.baseURL + '/uploads'"
              :show-file-list="false"
              :headers="getAuthHeaders()"
              :on-success="handleAvatarSuccess">
              <img v-if="model.avatar" :src="model.avatar" class="avatar">
              <i v-else class="el-icon-plus avatar-uploader-icon"></i>
            </el-upload>
  • 因为编辑和新建都在同一个界面,所以在<router-view/>需要添加一个key,这里使用 <router-view :key="$route.path"/>

2.新建文章

  • 编辑文章内容时使用了富文本编辑器vue-quil-editor

2.1 安装vue-quill-editor

npm install vue-quill-editor -save

2.2 安装vue-quill-editor

npm install quill -S

2.3 导入

  import 'quill/dist/quill.core.css'
  import 'quill/dist/quill.snow.css'
  import 'quill/dist/quill.bubble.css'
  import { quillEditor } from 'vue-quill-editor'
  import {quillRedefine} from 'vue-quill-editor-upload'

2.4 使用(包含文件上传)

<template>
	<quill-editor style="height:400px;" v-model="model.detail" :options="editorOption"/>
</template>
<script>
	components:{
	      quillEditor
	    },
created(){
	this.editorOption = quillRedefine(
	        {
	          // 图片上传的设置
	          uploadConfig: {
	            action:  this.$http.defaults.baseURL + '/uploads',  // 必填参数 图片上传地址,这里的后台是node
	            name: 'file',  // 必填参数 文件的参数名
	            methods: 'POST', // 必填参数 图片上传方式
	            // 必选参数  res是一个函数,函数接收的response为上传成功时服务器返回的数据
	            // 你必须把返回的数据中所包含的图片地址 return 回去
	            res: response => {
	              // 这里切记要return回你的图片地址
	              return response.url
	            }
	          },
	          theme:'snow'//这个是主题
	        }
	      )
	}
</script>

3.新建评论

在这里插入图片描述

3.1 建立 schema 和 model

//Articles.js
const monoogse = require('mongoose')
const Category = require('../models/Category')
const AdminUser = require('../models/AdminUser')
const Comment = require('../models/Comment')
const articleSchema = monoogse.Schema({
  categories:[{
    type:monoogse.SchemaTypes.ObjectId,
    ref:Category
  }],
  title:{
    type:String,
    require:true
  },
  image:{
    type:String,
    require:true
  },
  account:{
    type:String
  },
  date:{
    type:String
  },
  authorinfo:{
    type:monoogse.SchemaTypes.ObjectId,
    ref:AdminUser
  },
  detail:{
    type:String,
    require:true
  },
  comments:[{
    type:monoogse.SchemaTypes.ObjectId,
    ref:'Comment'
  }]
})
const Article = monoogse.model('Article',articleSchema)
module.exports = Article

3.1 获取文章列表

  • 这里做了分页和多层查询
	  let pageSize = parseInt(req.query.size) || 5;
      let currentPage = parseInt(req.query.page) || 1;
      queryOptions.limit = pageSize
      queryOptions.skip = (currentPage - 1) * pageSize
      const model = await req.Model.find().setOptions(queryOptions).populate({
        path:'authorinfo categories comments',
        populate:{
          path:'user'
        }
      })
      //获取总条数
      const all = await req.Model.find()
      const total = all.length
      res.send({total,list:model})
  • 查询的数据如下:
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43950643/article/details/107410986
今日推荐