碰到个业务需求,表单项有图片或文件上传需求,并且要求跟随表单数据一起走...

上传用element的el-upload组件

表单数据带着文件时,表单上传格式需要变动,需要使用 FormData 对象 ,而文件需要设置手动上传,并把获取到的文件添加到表单对象中,并把其他对单数据也逐步添加到表单对象

先介绍获取上传文件的方式,上传部分代码:

     <el-row style="width:500px;height:200px;float:right;">
        <el-col>
      <el-form-item label="用户头像"
                    prop="headUrl">
        <el-upload action=""
                   class="avatar-uploader"
                   :show-file-list="false"
                   ref="uploadImage"
                   :http-request="uploadImg"
                   :multiple="false"
                   :auto-upload="false"
                   :on-change="imgSaveToUrl"
                   :before-upload="beforeAvatarUpload"
                   accept="image/png,image/jpg,image/jpeg">
          <img v-if="dataForm.headUrl"
               :src="dataForm.headUrl"
               class="avatar" />
          <i v-else
             class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
      </el-form-item>
      </el-col>
      </el-row>

 上传部分样式:

<style>
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}
.avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

上传组件 action 为上传地址,这里是跟随表单走,所以设置为空,但action 必须有!!!,另外设置自动上传为 false,也可以设置多文件,或者列表形式上传或者设置文件格式和大小拦截,这里重点是 

:http-request="uploadImg"

这个属性绑定一个方法就是自定义上传方法,我们就是通过这个方法获取准备上传的文件,其他事件获取的文件用于上传时有问题。

注意:这个自定义方法是在组件使用submit后才会触发(大坑,折腾了好久才发现) 

上传前文件格式和大小判定代码:

beforeAvatarUpload (file) {
      const isJPG = file.type === 'image/jpeg' || 'image/png' || 'image/jpeg'
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!isJPG) {
        this.$message.error('上传头像图片只能是 JPG,PNG,JPEG 格式!')
      }
      if (!isLt2M) {
        this.$message.error('上传头像图片大小不能超过 2MB!')
      }
      return isJPG && isLt2M
 },

靠这个方法绑定change事件实现自定义图片回显:

    imgSaveToUrl (event) {
      if (this.beforeAvatarUpload(event)) {
        var URL = null
        if (window.createObjectURL != undefined) {
          // basic
          URL = window.createObjectURL(event.raw)
        } else if (window.URL != undefined) {
          // mozilla(firefox)
          URL = window.URL.createObjectURL(event.raw)
        } else if (window.webkitURL != undefined) {
          // webkit or chrome
          URL = window.webkitURL.createObjectURL(event.raw)
        }
        this.dataForm.headUrl = URL
      }
    },

其他详细看代码:

	//自定义上传方法,使用上传组件的submit()后才会触发以获取文件实体
    uploadImg (param) {
      this.img = param.file
    },
    // 表单提交
    dataFormSubmitHandle: debounce(
      function () {
        this.$refs.dataForm.validate((valid) => {
          if (!valid) {
            return false
          }
          this.$refs.uploadImage.submit() //必须使用此方法才会触发自定义上传方法以获取文件对象
          var form = new FormData() //携带文件必须使用此对象
          if (this.img) {
            form.append("file", this.img) 把文件实体添加到表单对象
          }
          let obj = {
            id: this.dataForm.id || undefined,
            username: this.dataForm.username,
            password: this.dataForm.password,
            confirmPassword: this.dataForm.confirmPassword,
            realName: this.dataForm.realName,
            idCard: this.dataForm.idCard,
            gender: this.dataForm.gender,
            email: this.dataForm.email,
            mobile: this.dataForm.mobile,
            mobile2: this.dataForm.mobile2,
            telephone: this.dataForm.telephone,
            wechat: this.dataForm.wechat,
            passportNum: this.dataForm.passportNum,
            appNum: this.dataForm.appNum,
            status: this.dataForm.status,
            appStatus: this.dataForm.appStatus,
            spell: this.dataForm.spell,
            pinyin: this.dataForm.pinyin,
            sort: this.dataForm.sort,
            superAdmin: this.dataForm.superAdmin,
            createDate: null,
            headUrl: this.dataForm.headUrl,
            masterDeptIdArr: this.dataForm.masterDeptIdArr,
            masterJobId: this.dataForm.masterJobId,
            slaveDeptJobList: this.dataForm.slaveDeptJobList
          }
		  //序列化其他数据为json添加到表单对象,后台反序列化获取对象实体,也可以单个append(),后台直接用对象取,如果一次性添加而不序列化会出错
          form.append("dto", JSON.stringify(obj)) 

          api.saveUser(form)
            .then((res) => {
              this.$message({
                message: this.$t('prompt.success'),
                type: 'success',
                duration: 500,
                onClose: () => {
                  this.visible = false
                  this.$emit('refreshDataList')
                },
              })
            })
            .catch(() => { })
        })
      },
      1000,
      { leading: true, trailing: false }
    ),

后台接收:

	@PostMapping
	@ApiOperation("保存")
	@LogOperation("保存")
	@RequiresPermissions("sys:user:save")
	public Result save(@RequestParam(required = false,name = "file") MultipartFile file, @RequestParam(name = "dto") String dto){
		JSONObject jsonObject = JSONObject.parseObject(dto);
		SysUserDTO sysUserDTO = JSONObject.parseObject(dto, SysUserDTO.class);
		
        //效验数据
		ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);
		
		if (file != null) {
			MultipartFile []files =new MultipartFile[1];
			files[0] = file;
			String headUrl = FileUtils.saveFile(files);
			sysUserDTO.setHeadUrl(headUrl);
		}
		sysUserService.save(sysUserDTO);

		return new Result();
	}

 

Logo

前往低代码交流专区

更多推荐