vue+element+springboot实现多张图片上传 您所在的位置:网站首页 国庆山东旅游景点 vue+element+springboot实现多张图片上传

vue+element+springboot实现多张图片上传

2024-06-14 04:39| 来源: 网络整理| 查看: 265

     1.需求说明      2.实现思路      3.el-upload组件主要属性说明      4.前端传递MultipartFile数组与服务端接收说明      5.完整代码

1.需求说明

    动态模块新增添加动态功能,支持多张图片上传.实现过程中对el-upload组件不是很熟悉,踩了很多坑,当然也参考过别的文章,发现处理很复杂.这里记录最终实现结果,方便有同样问题的同学查看,避免浪费多余时间.下面是发布动态的页面,点击上传图片打开本地文件选择,点击确定完成动态发布功能. 在这里插入图片描述

2.实现思路

    多张图片上传逻辑(兼容单张图片上传,只需要修改最大上传图片数量为1):     1.需要页面选择好所有图片之后调用服务端的图片上传接口,这样处理的原因是图片上传过程中会出现几种场景:

选择好图片之后要删除之前选择的某一张或某几张; 选择好图片之后要追加几张图片

如果按照选择一张就调用一次图片上传接口,不但会增加服务端调用次数,而且还会增加无效图片的存储成本.     2.多张图片一次上传接口调用成功后返回多张图片的图片地址,再调用服务端动态发布接口,完成动态发布功能

3.el-upload组件主要属性说明

1.禁用选择图片自动上传功能     action属性:图片上传服务端请求地址,在组件中属于必传,默认选择一张图片就要调用一次.按照上面梳理的逻辑需要禁用调用该功能,auto-upload设置为false即可.action由于是必传,所以此处设置为# 2.开启多选     设置multiple设置为true,默认false,否则在出现的文件选择窗口中只能选择一个文件. 3.设置选择文件最大数量     使用limit属性,超过最大数量的处理逻辑可以在on-exceed中实现,其中处理的逻辑是页面提示已超过最大数请重新选择. 4.显示已选择的图片列表     设置file-list实现 5.选择好图片之后追加几张图片问题处理     on-change可以监听选中的图片,一次性选择多个图片会执行多次,但是为保证业务处理逻辑执行成功,只需要最后一次on-change中添加业务处理,所以通过判断监听返回的fileList集合长度是否是最大来处理.自定义的fileList就是on-change中最后一次on-change监听返回的fileList集合信息.下文中自定义的imgUrlList为调用文件上传服务端组装的图片参数集合.服务端的file对象对应on-change监听file中的file.raw.

handleChange(file, fileList){ let length = fileList.length this.maxLength = Math.max(length, this.maxLength) setTimeout(() => { if(length !== this.maxLength) { return } else { this.fileList=fileList } }) }

6.选择好图片之后删除已选中图片问题处理     before-remove可以监听要进行删除的图片信息.每个图片中有一个唯一标识uid,通过唯一标识删除自定义fileList中的图片

handleRemove(file, fileList){ this.fileList=this.fileList.filter(imgFile=>imgFile.uid != file.uid) }, 4.前端传递MultipartFile[]与服务端接收说明

    服务端接口为post请求,请求方式为post表单提交.具体如下

@PostMapping("/uploadImg") public ResultVo uploadImg(@RequestParam(name = "multipartFiles") MultipartFile[] multipartFiles, @RequestParam(name = "fileType") Integer fileType) { String url = adminDriftService.adminUploadImg(multipartFiles,fileType); return ResultVoUtil.success(url); }

前端页面需要按照FormData类型进行传递,注意一下参数拼接:

let formData = new FormData(); this.imgUrlList.map(img=>{ formData.append("multipartFiles", img) }) formData.append("fileType", 2) 5.完整代码

    前端: dynamic.js:

export function uploadImg(formData) { return axios({ url: 'uploadImg', method: 'POST', data: formData }) }

新增动态弹窗:

点击上传 只能上传jpg/png文件,且不超过500kb 取 消 确 定 import {findSystemUserList,addDynamic,uploadImg} from "@/api/dynamic"; export default { data() { return { addDynamicVisible:false, // 是否显示新增动态弹窗 addDynamicForm:{}, // 新增动态内容 systemUserList:[], // 系统用户列表信息 formLabelWidth: '120px', imgUrlList:[], // 上传文件地址集合 fileList:[], // 上传文件本地显示图片集合(非服务器图片地址) maxLength:0 // 上传文件最大值 } } methods:{ // 图片列表删除之后处理操作 handleRemove(file, fileList){ this.fileList=this.fileList.filter(imgFile=>imgFile.uid != file.uid) }, // 每次打开本地文件选择窗口选择图片后处理操作 handleChange(file, fileList){ let length = fileList.length this.maxLength = Math.max(length, this.maxLength) setTimeout(() => { if(length !== this.maxLength) { return } else { this.fileList=fileList } }) }, // 选择图片超过最大限制9张之后处理操作 handleExceed(files, fileList){ this.msgError("最多选取9张,请重新选择!") // 清空之前选择内容 this.fileList=[] }, // 添加动态操作 addDynamicInfo(){ // 参数校验 if(!this.addDynamicForm.userId){ this.msgError("请选择用户!") return } this.imgUrlList=this.fileList.map(file=>file.raw) this.serverUploadImg() }, // 上传图片处理逻辑 serverUploadImg() { let formData = new FormData(); this.imgUrlList.map(img=>{ formData.append("multipartFiles", img) }) formData.append("fileType", 2) uploadImg(formData).then(res => { if (res.code === 200) { // 图片上传成功之后触发动态发布逻辑 this.addDynamicForm.contentImg=res.data this.serverAddDynamic() }else { this.msgError(res.msg) } }).catch(() => { this.msgError("请求失败") }) }, // 动态发布逻辑 serverAddDynamic() { addDynamic(this.addDynamicForm).then(res => { if (res.code === 200) { this.msgSuccess('添加成功!'); this.addDynamicVisible=false; this.addDynamicForm={}; this.imgUrlList=[]; this.fileList=[]; this.serverFindDynamicInfoList(this.queryInfo) }else { this.msgError(res.msg) } }).catch(() => { this.msgError("请求失败") }) }, }

服务端文件批量上传:

@ApiImplicitParams({@ApiImplicitParam(name = "multipartFiles",value = "图片集合",required = true, dataType = "MultipartFile[]"), @ApiImplicitParam(name = "fileType",value = "文件类型:1.用户图片:头像以及背景图;2.动态图",required = true, dataType = "Integer",paramType = "insert",example = "1")}) @ApiOperation("上传图片") @PostMapping("/uploadImg") public ResultVo uploadImg(@NotNull(message = "文件对象不允许为空!") @RequestParam(name = "multipartFiles") MultipartFile[] multipartFiles, @NotNull(message = "文件类型不允许为空!") @RequestParam(name = "fileType") Integer fileType) { String url = service.adminUploadImg(multipartFiles,fileType); return ResultVoUtil.success(url); }

多张文件上传实现逻辑:

public String adminUploadImg(MultipartFile[] multipartFiles, Integer fileType) { String imgUrlStr =""; for (int i = 0; i imgUrlStr=imgUrlStr+","; } } return imgUrlStr; }

图片上传具体实现逻辑:

public String uploadImg(MultipartFile multipartFile,Integer fileType,String fileNameParam) { // 返回文件地址 String fileUrl = ""; // 文件校验 checkFile(multipartFile,fileType); // 文件上传路径 // modify by txm 2023/3/24 图片类型修改为枚举 String filePath = FilePathEnum.getOSSFilePath(fileType); String fileName = StrUtil.isBlank(fileNameParam) ? multipartFile.getOriginalFilename():fileNameParam; String pathKey = StrUtil.concat(true,filePath,"/",fileName); // meta设置请求头 OSS ossClient = new OSSClientBuilder().build(driftConfig.getEndpoint(), driftConfig.getOssAccessKeyId(), driftConfig.getOssAccessKeySecret()); try { // 上传至阿里OSS ossClient.putObject(driftConfig.getBucketName(), pathKey, new ByteArrayInputStream(multipartFile.getBytes())); fileUrl = driftConfig.getUrlPrefix() + pathKey; } catch (Exception e) { // modify by txm 2023/10/16 修改描述 log.error("文件上传失败:{}", e.getMessage()); throw new BusinessException("文件上传失败:请重试!"); } finally { if (ossClient != null) { ossClient.shutdown(); } } // 上传成功 return fileUrl; }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有