从零开始,搭建一个简单的购物平台(四)

从零开始,搭建一个简单的购物平台(三):https://blog.csdn.net/time_____/article/details/105411636
项目源码(持续更新):https://gitee.com/DieHunter/myCode/tree/master/shopping

本篇文章延续上篇的登录界面搭建完成后,进行用户管理后端的编写,主要功能包括:

添加用户,上传头像

目录结构如下:

首先实现上传头像功能

上传文件流程:用户选择文件上传,服务端读取文件并生成唯一命名的缓存文件(二进制文件),将文件信息回传到前端,前端提交表单时将文件信息和用户信息一同上传至服务端,服务端读取对应文件,保存至public的img文件夹(此时生成的是图片文件),最后将图片路径存至数据库中

具体实现

  • 在controller文件夹下新建upload文件夹,在文件夹中新增upload.js用于上传头像,引入multer模块并进行文件暂存
    const router = require("express").Router();
    const Util = require("../../../utils/utils");
    var multer = require("multer");
    var upload = multer({
      dest: "./public/temp",//缓存目录
    });
    router.post(
      "/headPic",
      upload.single("headPic"),//单张图片,图片标识名
      Util.checkToken,//验证token
      (req, res) => {
        res.send({
          result: 1,
          msg: "上传成功",
          headPath: req.file,
        });
      }
    );
    
    module.exports = router;
    

     

  • 在router中添加upload.js的路由地址   app.use("/upload", upload);
    运行项目,做个测试,在postman中输入相对应地址和参数后点上传,服务端返回缓存文件信息并保存到缓存目录
  • 添加上传功能后,只是保证文件上传,还要把它转换成图片格式,所以在utils.js文件中新增几个方法(要引入fs模块),分别是:
    读取文件
     static readPicFile(_file) {
        let { path, mimetype } = _file;//获取文件路径和文件类型
        let file = fs.readFileSync(path);//将文件转换成二进制
        let fileName =//用时间戳加随机数命名文件
          new Date().getTime() +
          parseInt(Math.random() * Math.random() * 1000000) +
          "." +
          mimetype.split("/")[1];
        this.delPicFile(path);//删除之前的缓存文件
        return this.writePicFile(file, fileName);//写文件
      }
    保存(写入)文件
      static writePicFile(_file, _fileName) {
        let fileName = "./public/assets/img/" + _fileName;//文件路径
        fs.writeFileSync(fileName, _file);
        return fileName.split("./")[1];
      }
    删除文件 
    static delPicFile(_path) {
        fs.unlink(_path, (err) => {
          if (err) {
            console.log("删除失败");
          }
        });
      }
  • 全部完成后,上传文件也已完成 

添加用户功能

  • 在users.js界面中调取之前写的command(数据库增,删,改,查操作)
  • 由于增加操作可能是移动端用户注册,所以暂时不加token验证,由于邮箱和用户名是唯一值,所以需要先进行查找用户
    let findRes = await findData(Mod, {
        $or: [
          {
            mailaddress: res._data.mailaddress,
            mailurl: res._data.mailurl,
          },
          {
            username: res._data.username,
          },
          {
            mailaddress: res._data.username,
          },
          {
            username: res._data.mailaddress + res._data.mailurl,
          },
        ],
      });
      if (findRes && findRes.length > 0) {
        res.send({
          result: 0,
          msg: "添加失败,用户已存在",
        });
        Util.delPicFile(res._data.headPic);
        return;
      }

     

  •  判断到无此用户时,将其添加到数据库中
      if (res._data.headPic) {
        res._data.headPic = Util.readPicFile(res._data.headPic || "") || "";//保存头像
      }
      res._data.time = Util.joinDate();//添加时间
      res._data.password = Util.createBcrypt(res._data.password);//盐加密
      res._data.isactive = true;
      let addRes = await addData(Mod, res._data);
      if (addRes) {
        res.send({
          result: 1,
          msg: "添加成功",
        });
        return;
      }
      Util.delPicFile(res._data.headPic);
      res.send({
        result: 0,
        msg: "添加失败",
      });

     

  • 完成之后用postman测试一下,后端提示添加成功,数据库也成功添加该用户
     

文章到此,头像上传,用户添加就已经全部实现

总结

前后端项目请求应进行节流处理(即限制用户多次快速单击提交按钮),前后端双重保险,即可提升用户体验,又减少服务端压力,由于此项目主要以功能为主,在细节方面没有十分注重,真实线上项目必须添加节流

posted @ 2020-04-11 09:22  阿宇的编程之旅  阅读(94)  评论(0编辑  收藏  举报