SpringBoot + Vue 前后端分离(用户信息更新&头像上传&Markdown图片上传)

Posted HUTEROX

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot + Vue 前后端分离(用户信息更新&头像上传&Markdown图片上传)相关的知识,希望对你有一定的参考价值。

前言

说实话我是真没想到就这么简单的功能我还会踩坑,没办法前端写得烂,发送数据格式不对,后端的图片处理又不对,烦死了,不过还好后面有搞回来了,现在做个简单记录。到这里的话,后面就是如何整合那个Markdown编辑器,然后就是博客表的设计,分页获取数据,之后就是用户权限的设置,现在的话还没有后台管理,不过这个也好办主要是后面的文章审核,管理要用到,总的来说到周末还是有机会完成的,毕竟下个礼拜我要去展示一下我的项目作为期末作业,虽然这个是web的大二学校才刚刚教java,这次交个简单的桌面即可,但是这又不是我,理论上我还可以交安卓,交Flink的作品,但是前者没意思,uniapp香呀,还要啥安卓反正我又不是专业的前端,后者这玩意太抽象,我总不能说让Flink 跑个算法吧。所以web是比较理想的,刚好复习springboot 玩玩前后端分离。

用户信息更新

这个其实就是简单的CURD,后端拿到数据,然后更新即可,但是这里刚好涉及到用户验证,也就是token检测,这个可以去看看这篇
SpringBoot+Vue前后端分离实战(用户注册登录)
这个其实是一系列的记录。

这里几个比较重要的数据交互,一个是用户更新后的信息和状态,一个是token。

前端发送

<template>
  <div>
    <div class="show">
      <form>
      <p  style="margin-left:16%;margin-top: 3%;height:30px">昵称:<span style="margin-left: 5%"><input ref="username" :maxlength="10" placeholder="修改昵称" class="texti" style="height: 8%" type="text" maxlength="10"></input></span></p>
      <p  style="margin-left:16%;margin-top: 3%;height:30px">性别:<span style="margin-left: 5%"><input v-model="checkedman" ref="man" checked id="man" type="radio" value="1"  name="1" />&nbsp;&nbsp;&nbsp;<input v-model="checkedman" ref="woman" id="woman" type="radio" value="2" name="1"/></span></p>
      <p  style="margin-left:16%;margin-top: 3%;height:30px">邮箱:<span style="margin-left: 5%"><input  ref="email" :maxlength="30" id="emailAddress" type="email" placeholder="修改邮箱" style="height: 8%" class="texti"></input></span></p>
      <p  style="margin-left:16%;margin-top: 3%;height:200px">简介:<span style="margin-left: 5%"><textarea ref="jianjie" style="  width: 60%;height: 80%;"  class="texti" placeholder="请开始编辑"></textarea></span></p>
        <el-button style="margin-left: 10%;width: 20%;height: 15%" class="btn" @click="cancle()">取消</el-button>
        <el-button style="margin-left: 40%;width: 20%;height: 15%" class="btn" @click="submitForm()">确定</el-button>
      </form>
    </div>
  </div>
</template>

<script>
//还是等跳转到这里的时候再来加载数据好一点

export default 

  name: "changeinfo",
  beforeRouteEnter: (to, from, next) => 
    console.log("准备进入个人信息页");
    let islogin = localStorage.getExpire("tokenhole")
    if(!islogin)
      next(path:'/login');
    
    next();
  ,
  data()
    return
      checkedman:"1",
      checkedwoman:""

    
  ,
  methods:
    cancle()
      this.$router.push("/space")
    ,

    changeinfo()
      this.axios(
        url: "/boot/space/changeuserinfo",
        method: 'post',
        headers:  "token": localStorage.getExpire("tokenhole") ,
        data: 
          name: this.$userinfo.userName,
          email: this.$userinfo.userEmail,
          sex: this.$userinfo.userSex,
          userinfo: this.$userinfo.userInfo
        ,

      ).then(res =>
        let data = res.data
        if(data.success == '0')
          alert("数据提交异常请重新提交~")
        
        else 
          alert("信息修改成功")
          this.$router.push("/space")
        

      )
    
    ,
    submitForm()
    //  先改变本地的数值,然后上传到服务器

      if(this.$refs.email.value!='')

        if(this.$refs.email.value!==this.$userinfo.userEmail)
          if(this.$refs.email.value.indexOf("@") >= 0)
            this.$userinfo.userEmail = this.$refs.email.value
          
          else 
            alert("请输入正确的邮箱地址!")
            return
          

        
      

      if(this.$refs.jianjie.value!='')
        if(this.$refs.jianjie.value!==this.$userinfo.userInfo)
          this.$userinfo.userInfo= this.$refs.jianjie.value
        
      

      if(this.$refs.username.value!='')
        if(this.$refs.username.value!==this.$userinfo.userName)
          this.$userinfo.userName = this.$refs.username.value
        
      


    //  由于男女是存储值的,所以还是要判断一下的,默认是男的所以只需要看看是说不是小姐姐就好了
      if(this.checkedwoman===2)
        this.$userinfo.userSex='女'
      


    //这部分是后面和后端打交道的,最后回去space页面
    this.changeinfo()

    

  

</script>

<style scoped>
.show
  margin: 100px auto;
  width: 80%;
  height: 450px;
  border: 5px solid #18a0ec;
  transition: all 0.9s;
  border-radius: 10px;



.show:hover
  box-shadow: 0px 15px 30px rgba(0, 0, 0, 0.4);
  margin-top: 90px;


.texti
  border: 1px solid #ccc;
  padding: 13px 14px;
  width: 30%;

  font-size: 14px;
  font-weight: 300;

  border-radius: 5px; /* 边框半径 */
  background: white; /* 背景颜色 */
  cursor: pointer; /* 鼠标移入按钮范围时出现手势 */
  outline: none; /* 不显示轮廓线 */



.texti:focus
  border-color: #1e88e1;
  outline: 0;
  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);
  box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)

textarea 
  resize: none;


</style>

这个前端基本上就是直接硬怼的,没有啥技巧。

那个用户信息是个全局变量


这样当用户信息更新之后能够及时在前端显示。

后端接口

到了这里就是后端接口

 public SpaceMessage ChangeUserInfo(HttpServletRequest request,
                                       @RequestBody Map<String, Object> usermap) throws Exception 
        String token = request.getHeader("token");

        User user = VerifyUser(token);

        String name = (String) usermap.get("name");
        String email = (String) usermap.get("email");
        String sex = (String) usermap.get("sex");
        String userinfo =(String) usermap.get("userinfo");

        user.setUserInfo(userinfo);
        user.setUserEmail(email);
        user.setUserSex(sex);
        user.setChengHu(name);

        boolean flag = userService.UpdataUser(user);
        if(flag)
            spaceMessage.setSuccess(1);
        else
            spaceMessage.setSuccess(0);
        return spaceMessage;
    

但是这里的话由于整个项目的分层比较多所以只能把核心的拿过来看看。(项目源码后面会在GitHub开源,这个只是相当于记录)

修改用户头像

这个还是比较重要的,后面那个Markdown的图片显示也还用的上。

前端

前端图片显示

这里的话你可以选择上传之后服务器返回图片url,但是我这里是选择在前端自己加载了本地的图片(也是把先前的老代码拿了过来改一下)

changepic() 
      document.getElementById('file').onchange = function () 
        var imgFile = this.files[0];
        var fr = new FileReader();

        fr.onload = function () 
          let showing = document.getElementById('showimg')
          let img = fr.result;
          this.f64 = img;
          this.filename = imgFile.name
          showing.src = img;
          showing.style.height = "220px";
          showing.style.width = "220px";
          showing.style.borderRadius="200px"
        ;
        fr.readAsDataURL(imgFile);
      
      

图片上传

这里要说的就是那个这里还是用 axios发送的那玩意默认是把数据放在 body 了,所以这里封装一个

let param = new FormData();
这样就好了,这样就不会放在那里了,这样后端就好接受了,否则拜拜~

 subchangepic()


      if(this.$refs.file.files[0]!=null)
        this.f64 = this.$refs.file.files[0]
        console.log(this.f64.name)
        let param = new FormData();
        param.append("file",this.f64);
        this.axios(
          url: "/boot/space/changepic",
          method: 'post',
          headers: 
            'Content-Type': 'multipart/form-data',
            "token": localStorage.getExpire("tokenhole"),
          ,
          data: param,

        ).then(res=>
          if(res.data.success == '0')
            alert("头像上传失败请检查图片格式")
          
          else 
            alert("信息修改成功")
            this.$router.push("/space")
          
        )
      

完整 代码

<template>
  <div>
    <div class="show">
        <div class="show1" >
          <img ref="showing" src="" id="showimg" style="margin-left: 1px;margin-top: 3px">
        </div>
        <br>
        <input multiple="multiple" id="file" ref="file" @click="changepic(this)" type="file" name="userpic"
               style="前后端分离 Vue + Springboot 实现用户列表单页面开发(建议收藏)

SpringBoot+Vue前后端分离实战(用户注册登录)

博客基于SpringBoot+vue的前后端分离颜值博客系统

基于前后端分离的授权及认证(Shiro-SpringBoot-Vue)

基于JAVA springboot+VUE前后端分离疫情防疫平台设计实现

Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)十九(用户中心)