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

本文最后更新于:9 个月前

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

这篇文章将前后端管理功能完成,也就是将最后修改用户信息功能实现(由于商品管理与用户管理类似,所以不做描述),并讲述一下遇到的坑

修改用户数据后端其实就是根据用户id,将从前端传来的字段对应的值更新,如果头像有变化,则删除之前用户的头像,前端相对服务端反而更繁琐一些,当用户点击修改用户信息按钮后,将用户信息初始化到form表单中(头像同样需要加载),这里考虑到初始化用户信息的实现可以直接获取表格中的数据,可减少一次请求,但是有个小坑,当用户点击修改时,Drawer组件中的form表单初始化是异步的,需要两个解决操作:1.将Drawer中的子组件预加载(开启Drawer中的forceRender属性)。2.将form初始化操作放到form更新渲染完成之后(componentDidUpdate ),如果放在componentDidMount中,组件初始化只会进行第一次,下一步,直接开始整后端

  • 服务端在command中新增update方法
/* 更新数据
  * @param {object} mod       数据库model
  * @param {string} _id       数据唯一标识
  * @param {object} data      更新字段及值
  */
 static updateData(mod, _id, data) {
   //改
   return mod
     .updateOne(
       {
         _id,
       },
       data
     )
     .then((res) => {
       return res;
     })
     .catch((err) => {
       return false;
     });
 }
  • 在user.js文件中添加接口用于更新用户信息
router.post(Config.ServerApi.updateUser, Util.checkToken, async (req, res) => {
  if (!res._data.headPic.length) {//这里判断是否是修改头像,若是新增,则是上传相关的头像信息,是个object类型,length属性不存在
    let findRes = await findData(Mod, {
      _id: res._data._id,
    });
    if (findRes[0].headPic != "public/assets/img/default.gif") {
      Util.delPicFile(findRes[0].headPic);
    }
    res._data.headPic = Util.readPicFile(res._data.headPic || "") || "";
  }
  res._data.password = Util.createBcrypt(res._data.password);//密码盐加密
  let updateRes = await updateData(Mod, res._data._id, res._data);
  if (updateRes) {
    res.send({
      result: 1,
      msg: "修改成功",
    });
    return;
  }
  Util.delPicFile(res._data.headPic);
  res.send({
    result: 0,
    msg: "修改失败",
  });
});

之后我们看看前端功能实现

前端需要在之前实现的新增用户中做修改,达到相关目的

  • 在upload.js组件中添加初始化显示图片功能,也就是渲染组件时给个src,并且把方法传递给父组件以供调用(放到componentDidMount中),在父组件通过组件属性为子组件设置this中的属性达到调用。当然也可以使用全局events传递参数
this.props.onUpdateRef(this);//放在子组件中,使父组件调用当前组件
onUpdateRef={(child) => {//放在父组件的子组件的属性里,通过this.updateChild调用子组件的this
    this.updateChild = child;
 }}

updatePic(url) {
   if (url && url.length > 0) {
     this.setState({
       fileList: [
         {
           uid: "-1",
           name: url,
           status: "done",
           url,
         },
       ],
     });
   }
 }
  • 全部实现后,可以在自定义的drawer.js组件进行新增用户和修改用户的区分
showDrawer = (record) => {
    if (record) {//传递了参数说明是更新信息,否则是新增用户
      this.setState({
        formType: "updata",
        visible: true,
        record,
      });
      this.updateChild.updatePic(FilePath + record.headPic);//调用上传头像组件,显示图片
    } else {
      this.setState({
        formType: "add",
        visible: true,
        record: {//新增用户的初始值
          sex: "man",
          userType: "user",
          mailurl: "@qq.com",
        },
      });
    }
  };
  • 在componentDidUpdata中添加更新form方法,将state中的record初始化至form中
componentDidUpdate() {
    this.formRef.current.setFieldsValue(this.state.record);
}
  • 在Drawer隐藏方法中将表单初始化并清空state中的record
onClose = () => {
    this.formRef.current.resetFields();
    this.setState({
      visible: false,
      record: null,
    });
 };

效果如下

最后,我们试试将数据提交至后端

总结:

到现在为止,项目中的用户管理前端+服务端功能已全部实现,商品管理的功能实现与用户同理,但是字段名不同,不做说明,下一篇文章直接开始搭建商城前端及后端功能