当前位置:   article > 正文

Ruoyi-vue上传下载文件_若依 文件上传

若依 文件上传

1. Controller

  1. /**
  2. * 修改文书发布记录
  3. */
  4. @RepeatSubmit //禁止重复提交
  5. @Log(title = "文书发布记录", businessType = BusinessType.UPDATE)
  6. @PostMapping("update") //@RequestParam("xxx") @RequestBody @RequestPart("xxx") 这3个注解都不能使用,否则会报错
  7. public AjaxResult edit(ReleaseRecord releaseRecord, MultipartFile uploadFile1, MultipartFile uploadFile2) throws Exception {
  8. String name1 = FileUploadUtils.uploadByPcRelease("location1", uploadFile1);
  9. String name2 = FileUploadUtils.uploadByPcRelease("location2", uploadFile2);
  10. releaseRecord.setAttachment1(name1); //上传路径保存数据库
  11. releaseRecord.setAttachment2(name2);//上传路径保存数据库
  12. return toAjax(releaseRecordService.updateReleaseRecord(releaseRecord, uploadFile1, uploadFile2));
  13. }

2. FileUploadUtils.java (不太喜欢官方那种格式,因此以下方法是复制官方的写法再改成自己的,)

// return getPathFileName(baseDir, fileName);//官方默认 返回 资源映射路径 

返回profile/ + 文件路径+文件名 (其中profile会自动隐射到yml设置的上传路径,但是前后端的端口不一致会有跨域问题,因此前端会加上process.env.VUE_APP_BASE_API作为前缀,而这个前缀代理会跳转到后台接口)
 -- 前端配置
      process.env.VUE_APP_BASE_API = 'http://localhost/dev-api'
  -- 使用代理来解决跨域问题
      http://localhost/dev-api -> http://localhost:8080
 -- 解析前端请求 /dev-api
     http://localhost/dev-api/profile/location1/yyyymmdd/xxx.pdf
 -- 此时,再将请求交给后端处理  --这样就真正的拿到文件了
      http://localhost:8080/profile/location2/yyyymmdd/xxx.pdf

  1. /**
  2. * 文件上传
  3. *
  4. * @param baseDir 相对应用的基目录
  5. * @param file 上传的文件
  6. * @return 返回上传成功的文件映射路径(非绝对路径)
  7. * @throws FileSizeLimitExceededException 如果超出最大大小
  8. * @throws FileNameLengthLimitExceededException 文件名太长
  9. * return getPathFileName(baseDir, fileName);//官方默认 返回 资源映射路径 (前缀:profile/)
  10. //返回profile/ + 文件路径+文件名 (其中profile会自动隐射到yml设置的上传路径,但是前后端的端口不一致会有跨域问题,因此前端会加上process.env.VUE_APP_BASE_API作为前缀)
  11. -- 前端配置
  12. process.env.VUE_APP_BASE_API = 'http://localhost/dev-api'
  13. -- 使用代理来解决跨域问题
  14. http://localhost/dev-api -> http://localhost:8080
  15. -- 解析前端请求 /dev-api
  16. http://localhost/dev-api/profile/avatar/2021/06/17/xxx.jpeg
  17. -- 此时,再将请求交给后端处理 --这样就真正的拿到文件了
  18. http://localhost:8080/profile/avatar/2021/06/17/xxx.jpeg
  19. */
  20. public static final String uploadByPcRelease(String baseDir, MultipartFile file) throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, InvalidExtensionException{
  21. int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
  22. if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) { //文件名长度不能超过100
  23. throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
  24. }
  25. //带格式的文件名
  26. String fileName = StringUtils.format("{}/{}.{}", DateUtils.dateTime(), FilenameUtils.getBaseName(file.getOriginalFilename()), getExtension(file));
  27. String absPath = getAbsoluteFile(getDefaultBaseDir() + baseDir, fileName).getAbsolutePath(); //获取实际绝对路径
  28. file.transferTo(Paths.get(absPath));//把文件 移到 绝对路径
  29. return Constants.RESOURCE_PREFIX + baseDir + fileName; //返回映射路径 (映射路径不包含 默认路径 getDefaultBaseDir ,会自动隐射到这个默认路径)
  30. }

3. 上传组件

  1. <el-col :span="12" >
  2. <el-form-item :label="uploadTitle1" label-width="150px" prop="uploadFile1">
  3. <template>
  4. <el-upload class="upload-demo" :file-list="fileList1" action="#" :auto-upload="false" :multiple="false" v-model="form.uploadFile1"
  5. :http-request="uploadFile1" :accept="fileType" ref="uploadExcel1" :on-change="changeFile1" :on-remove="handleRemove1">
  6. <el-button type="primary" >选择文件</el-button>
  7. <div slot="tip" class="el-upload__tip">大小不超过10mb</div>
  8. </el-upload>
  9. </template>
  10. </el-form-item>
  11. </el-col>
3.1下载组件:
 <el-link type="primary" :href="downLoadUrl + form.attachment1" v-if="form.attachment1">下载</el-link>
3.2 js
  1. export default {
  2. name: "xxx",
  3. data() {
  4. return {
  5. fileType: ".xlsx, .xls", //上传文件的类型
  6. uploadTitle1: '每日计划',
  7. fileList1:[], //附件上传列表
  8. downLoadUrl :process.env.VUE_APP_BASE_API , //默认请求前缀--解决(前端81到后端8080)跨域问题
  9. form: {},// 表单参数
  10. }
  11. }
  12. methods: {
  13. //自定义上传方法,使用上传组件的submit()后才会触发以获取文件实体
  14. uploadFile1(param) {
  15. this.form.uploadFile1 = param.file;
  16. },
  17. changeFile1(file, fileList) {
  18. if (fileList.length > 1) {
  19. fileList.splice(0, 1);
  20. }
  21. this.fileList1 = fileList;
  22. },
  23. handleRemove1(file){
  24. this.fileList1 = [];
  25. },
  26. validationFile(){ //附件校验
  27. this.$refs.uploadExcel1.submit(); //触发上传组件提交方法uploadFile(param)
  28. let title1 = this.uploadTitle1; //附件标题 1
  29. let file1 = this.form.uploadFile1 ;
  30. if(file1 == null){
  31. this.$modal.msgError(title1 + '附件不能为空');
  32. return false;
  33. }
  34. return true;
  35. },
  36. addFormData(form) { //把表单元素转换成FormData类型,表单与上传文件同时提交就必须转,否则无法上传
  37. let formData = new FormData();
  38. for (let key in form) {
  39. //字段为null不传到后台,否则会转成string类型的null导致数据错误 ,集合类型xxxList也剔除掉,因为为null后台也会报错
  40. if (form.hasOwnProperty(key) && form[key] != null && form[key] != 'null' && key != 'xxxList') {
  41. formData.append(key, form[key]);
  42. }
  43. }
  44. return formData;
  45. },
  46. /** 提交按钮 */
  47. submitForm(op, optext) {
  48. this.$refs["form"].validate(valid => { //触发表单所有项的校验规则检查
  49. if (valid) { // 表单校验通过才执行
  50. if(!this.validationFile()){//只有发布才能上传附件,才能更改配布对象
  51. return;//附件校验不通过就结束
  52. }
  53. let formData = this.addFormData(this.form) ; //把表单对象转成FormData对象 (上传文件必须使用FormData对象)
  54. request({ url: '/update', method: 'post', data: data});//提交到后台
  55. }
  56. });
  57. },
  58. }

4. 附件回显:

  1. //用于回显附件
  2. private void setFileListIfNotNull( String url, Consumer<List<El_UploadEntity>> setter) {
  3. if (StringUtils.isNotBlank(url)) {//附件链接不为空
  4. List<El_UploadEntity> fileList = new ArrayList<>();
  5. String fileName = new File(url).getName();//转文件再获取文件名是最简单有效的
  6. fileList.add(new El_UploadEntity(fileName, url));//生成一个fileList
  7. setter.accept(fileList); //把fileList赋值给实体,这种写法比较便利,以后有多个文件只需要把set方法作为参数传进来即可,accept就会自动赋值
  8. }
  9. }
  10. public ReleaseRecord selectReleaseRecordById(Long id) {
  11. ReleaseRecord r = releaseRecordMapper.selectReleaseRecordById(id);
  12. setFileListIfNotNull(r.getAttachment1(), r::setFileList1);
  13. //setFileListIfNotNull(r.getAttachment2(), r::setFileList2);多个附件多次调用
  14. return r;
  15. }

 el-upload上传组件的file-list指定的实体,传到前台需要传List<El_UploadEntity>类型才能解析

  1. import lombok.AllArgsConstructor;
  2. import lombok.Data;
  3. import lombok.NoArgsConstructor;
  4. import java.io.Serializable;
  5. @Data
  6. @NoArgsConstructor
  7. @AllArgsConstructor
  8. public class El_UploadEntity implements Serializable {
  9. private String name;
  10. private String url;
  11. }

 

在前端中只需在根据ID获取数据的方法中把上传组件的:file-list=指定为上面r::setFileList1中的fileList1即可

重点:

  1. 假如保存到数据库的路径是:/profile/aaa/20231211/bbb.xlsx ,那么前端鼠标划过下载文件显示的路径必须是 process.env.VUE_APP_BASE_API + /profile后面这一串

否则无法找到文件会一直404

2. 若想上传组件的on-change方法有效,那么limit需要删除,否则无效

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/594991
推荐阅读
相关标签
  

闽ICP备14008679号