el-upload上传图片图片、el-load默认图片重新上传、el-upload初始化图片、el-upload编辑时回显图片

  • 问题
    我用el-upload上传图片,再上一篇文章已经解决了,el-upload上传图片给SpringBoot后端,但是又发现了新的问题,果然bug是一个个的冒出来的。新的问题是el-upload编辑时回显图片的保存
    • 问题描述:回显图片需要将默认的 file-list设置为data中的属性,以设置默认值。如下,设置为imgList
 <el-upload
            action=""
            list-type="picture-card"
            multiple
            :on-change="handlChange"
            :file-list="imgList"
            :on-error="handleErr"
            ref="upload"
            :limit="10"
            accept=".jpg,.png,.jpeg"
            :on-exceed="handleMaxNum"

            :auto-upload="false">
            <i slot="default" class="el-icon-plus"></i>
            <div slot="file" slot-scope="{file}">
              <img
                class="el-upload-list__item-thumbnail"
                :src="file.url" alt=""
              >
              <span class="el-upload-list__item-actions">
                <span
                  class="el-upload-list__item-preview"
                  @click="handlePictureCardPreview(file)"
                >
                  <i class="el-icon-zoom-in"></i>
                </span>

                <span

                  class="el-upload-list__item-delete"
                  @click="handleRemove(file)"
                >
                  <i class="el-icon-delete"></i>
                </span>
              </span>
            </div>
          </el-upload>

但是这样的自己设置的值,他的格式是这样的:

this.imgList = this.imgList.map(url => ({
          url: url,
        })

与自己上传文件通过:file_list得到的内容不同,(也就是如果你有个添加图片的功能,有个编辑图片的功能,编辑功能你要设置初始值,但是他们的imgList不一样),有图为证
在这里插入图片描述
在这里插入图片描述
这会导致什么呢?首先,我们需要将imgList的文件转成FormData格式的文件传给后端,通过获取file-ist,可以通过:on-change="handlChange"获取

 handleChange(file, fileList) {
      this.imgList = fileList;
    },
  1. 如果你是添加图片的功能的时候,他是没问题的,可以直接使用
    formData.append('files', item.raw);转成FormData的类型。
  2. 但是如果你是要回显图片再保存,即编辑的功能,这个时候你要设置初始值,即用上面所说的方式设置。这种格式的的imgList,就不能直接使用 formData.append('files', item.raw);这种方式转成FormData,而要使用fetch的方式
  • 解决
    下面是解决的代码,可以先对imgList的url进行判断,因为自己上传的url开头是不带"blob"的,顺便说一下,因为fetch是异步的,所以要通过设置Promise,等fetch全部执行完再进行保存图片,否则FormData还是会为空
this.imgList.forEach(item => {
    let url = item.url;
    if(url.startsWith("blob")){
      formData.append('files', item.raw);
    }
    else {
      let promise = fetch(url, {
          headers: new Headers({
            'Origin': location.origin
          }),
          mode: 'no-cors'
        }
      )
        .then(response => response.blob())
        .then(blob => {
          // 创建 URL 对象以便提取文件名

          let filename = url.split('/').pop();

          // 创建一个虚拟的 File 对象
          let file = new File([blob], filename, {type: 'image/bmp,image/jpeg,image/png,image/webp'});
          console.log(file)
          formData.append('files', file);

        })
        .catch(error => {
          console.error('Failed to fetch image:', error);
        });
      promises.push(promise);
    }
  });
  Promise.all(promises).then(() => {
  console.log("formdata", formData)

         let uri = "/" + newAttractionId
         saveImgs(uri, formData)
           .then(resPic => {
             if (resPic.data.success) {
               // this.$message({
               //   type:"success",
               //   message:resPic.data.msg
               // })
             } else {
               this.$message({
                 type: "info",
                 message: resPic.data.msg
               })
             }

           }).catch(err => {
           console.log("出错", err)
         })

整合主要代码如下

<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
  <el-dialog :title="title" :visible.sync="editFormVisible" width="35%" @click="closeDialog">
     <el-form-item label="图片" prop="imgList">
          <!--          :file-List可以填默认值-->
          <el-upload
            action=""
            list-type="picture-card"
            multiple
            :on-change="handleChange"
            :file-list="imgList"
            :on-error="handleErr"
            ref="upload"
            :limit="10"
            accept=".jpg,.png,.jpeg"
            :on-exceed="handleMaxNum"

            :auto-upload="false">
            <i slot="default" class="el-icon-plus"></i>
            <div slot="file" slot-scope="{file}">
              <img
                class="el-upload-list__item-thumbnail"
                :src="file.url" alt=""
              >
              <span class="el-upload-list__item-actions">
                <span
                  class="el-upload-list__item-preview"
                  @click="handlePictureCardPreview(file)"
                >
                  <i class="el-icon-zoom-in"></i>
                </span>

                <span

                  class="el-upload-list__item-delete"
                  @click="handleRemove(file)"
                >
                  <i class="el-icon-delete"></i>
                </span>
              </span>
            </div>
          </el-upload>
        </el-form-item>
      </el-form>
      
data() {  

      imgList: [],
}
methods: {
handleRemove(file) {

      let arr = this.$refs.upload.uploadFiles
      console.log("arr是",arr)
      // 2.从pics数组中,找到图片对应的索引值
      let index = arr.indexOf(file)
      // 3.调用splice方法,移除图片信息
      arr.splice(index, 1)
      this.imgList=arr
      console.log(this.imgList)

    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    handleChange(file, fileList) {
      this.imgList = fileList;
    },
    handleMaxNum() {
      this.$message({
        type: "info",
        message: "最多选择10张图片"
      })
    },
// 编辑、增加页面保存方法
    subm**加粗样式**itForm(editData) {
      this.loading = true

      this.$refs[editData].validate(valid => {
          if (valid) {
            attractionSave(this.editForm)
              .then(res => {
                  this.editFormVisible = false

                  // console.log(res)
                  if (res.data.success) {

                    let newAttractionId = res.data.attractionId

                    //信息保存成功后,保存图片
                    if ( newAttractionId != '') {
                      let formData = new FormData(); // 用 FormData 存放上传文件

                      // 将图片转为 FormData 格式
                      let promises = [];
                      this.imgList.forEach(item => {
                        let url = item.url;
                        if(url.startsWith("blob")){
                          formData.append('files', item.raw);
                        }
                        else {
                          let promise = fetch(url, {
                              headers: new Headers({
                                'Origin': location.origin
                              }),
                              mode: 'no-cors'
                            }
                          )
                            .then(response => response.blob())
                            .then(blob => {
                              // 创建 URL 对象以便提取文件名

                              let filename = url.split('/').pop();

                              // 创建一个虚拟的 File 对象
                              let file = new File([blob], filename, {type: 'image/bmp,image/jpeg,image/png,image/webp'});
                              console.log(file)
                              formData.append('files', file);

                            })
                            .catch(error => {
                              console.error('Failed to fetch image:', error);
                            });
                          promises.push(promise);
                        }
                      });


                      Promise.all(promises).then(() => {
                        console.log("formdata", formData)

                        let uri = "/" + newAttractionId
                        saveImgs(uri, formData)
                          .then(resPic => {
                            if (resPic.data.success) {
                              // this.$message({
                              //   type:"success",
                              //   message:resPic.data.msg
                              // })
                            } else {
                              this.$message({
                                type: "info",
                                message: resPic.data.msg
                              })
                            }

                          }).catch(err => {
                          console.log("出错", err)
                        })
                      })
                    }


                    this.$message({
                      type: 'success',
                      message: res.data.msg
                    })
                  } else {
                    this.$message({
                      type: 'info',
                      message: res.data.msg
                    })
                  }

                }
              )
              .catch(err => {
                this.editFormVisible = false
                this.loading = false
                this.$message.error('保存失败,请稍后再试!')
                console.log(err)

                return false
              })
            var that = this
            setTimeout(function () {
              that.loading = false;
              that.getData()
            }, 1000)

          } else {
            this.loading = false
            return false
          }
        }
      )

    },
     //显示编辑界面
    handleEdit: function (index, row) {

      this.editFormVisible = true
      if (row != undefined && row != 'undefined') {
        this.title = '修改';
        this.imgList=row.imgList
        this.imgList = this.imgList.map(url => ({
          url: url,
        }));
        console.log("list", this.imgList)

      } 
    }
  </el-dialog>

同时,附上SpringBoot业务层代码

  @Override
    public ResJson savePicture(List<MultipartFile> files, String attractionLocationById) {
        ResJson resJson = new ResJson();
        // 获取文件夹中所有文件的列表
        File file1 = new File(attractionLocationById);
        File[] folderFiles = file1.listFiles();

         // 创建一个 HashSet,用于存储上传文件的名称
        Set<String> uploadedFileNames = new HashSet<>();
        if(files==null) {
            for (File folderFile : folderFiles) {
                if (folderFile.delete()) {

                    System.out.println("删除文件: " + folderFile.getName() + " 成功");
                } else {
                    System.out.println("删除文件: " + folderFile.getName() + " 失败");
                }
            }
            file1.delete();
            return null;
        }
        for (MultipartFile file : files) {
            uploadedFileNames.add(file.getOriginalFilename());
        }

        System.out.println("uploadedFileNames = " + uploadedFileNames);


        //删除图片,其实只要全部删除,再重新下载即可,考虑到图片数量可能多,就搞成判断了
        if(folderFiles!=null) {
            // 遍历文件夹中的文件
            for (File folderFile : folderFiles) {
                String folderFileName = folderFile.getName();
                // 如果文件夹中的文件不在上传的文件列表中,则删除该文件

                if (!uploadedFileNames.contains(folderFileName)) {
                    System.out.println(folderFileName);
                    if (folderFile.delete()) {

                        System.out.println("删除文件: " + folderFile.getName() + " 成功");
                    } else {
                        System.out.println("删除文件: " + folderFile.getName() + " 失败");
                    }
                }
                else{
                    uploadedFileNames.remove(folderFileName);
                }

            }
        }


        // 保存上传的文件
        for (MultipartFile file : files) {
            try {

                String originalFilename = file.getOriginalFilename();
                //如果已经有了,在上面的被移除了,只有在剩下的没被排除内的就下载
                if(uploadedFileNames.contains(originalFilename)) {
                    // 构建真实的文件路径
                    Path path = Paths.get(attractionLocationById + originalFilename);

                    // 确保目录路径存在
                    Files.createDirectories(path.getParent());
                    // 将上传文件保存到指定位置
                    file.transferTo(path);
                    System.out.println("图片保存成功");
                    System.out.println("保存+1");
                }
                resJson.setMsg("图片保存成功");
                resJson.setSuccess(true);
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("上传失败");
                resJson.setMsg("图片保存失败");
                resJson.setSuccess(false);
            }

        }

        return resJson;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/506179.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从0配置React

在本地安装和配置React项目&#xff0c;您可以使用create-react-app这个官方推荐的脚手架工具。以下是安装React的步骤&#xff0c;包括安装Node.js、使用create-react-app创建React应用&#xff0c;以及启动开发服务器。 下载安装node.js运行以下命令&#xff0c;验证Node.js…

施耐德 Unity Pro PLC 编程软件介绍

Unity Pro 软件基本介绍 Unity Pro 是施耐德中大型 PLC 的编程软件&#xff08;<–> 对应西门子 Step7&#xff09; 支持的 PLC&#xff1a;施耐德中大型 PLC 中型 PLC&#xff1a;Premium、M340&#xff08;<–> 对应西门子 S7-300、S7-1200&#xff09;大型 PL…

精读 Generating Mammography Reports from Multi-view Mammograms with BERT

精读&#xff08;非常推荐&#xff09; Generating Mammography Reports from Multi-view Mammograms with BERT&#xff08;上&#xff09; 这里的作者有个叫 Ilya 的吓坏我了 1. Abstract Writing mammography reports can be errorprone and time-consuming for radiolog…

C++项目——集群聊天服务器项目(十)点对点聊天业务

本节来实现C集群聊天服务器项目中的点对点聊天业务&#xff0c;一起来试试吧 一、点对点聊天业务 聊天服务器中一个重要的功能就是实现点对点聊天&#xff0c;客户端发送的信息包含聊天业务msgid、自身 的id和姓名、聊天对象的id号以及聊天信息&#xff0c;例如&#xff1a; …

uniapp uni.scss中使用@mixin混入,在文件引入@include 样式不生效 Error: Undefined mixin.(踩坑记录一)

问题&#xff1a; 在uni.scss文件定义mixin 2. 在vue文件引入: 3. 出现报错信息: 4. 问题思考&#xff1a; 是不是需要引入uni.scss &#xff1f; 答案不需要 uni.scss是一个特殊文件&#xff0c;在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。uni-app的…

ubuntu23.10配置RUST开发环境

系统版本: gcc版本 下载rustup安装脚本: curl --proto https --tlsv1.2 https://sh.rustup.rs -sSf | sh下载完成后会自动执行 选择默认安装选项 添加cargo安装目录到环境变量 vim ~/.bashrc 默认已添加 使用环境变量立即生效 source ~/.bashrc 执行rust开发环境,在终端输入…

Vitepress部署到GitHub Pages,工作流

效果&#xff1a; 第一步&#xff1a; 部署 VitePress 站点 | VitePress 执行 npm run docs:build&#xff0c;npm run docs:preview&#xff0c;生成dist文件 第二步&#xff1a; 手动创建.gitignore文件&#xff1a; node_modules .DS_Store dist-ssr cache .cache .temp *…

KMP哈希算法

KMP算法 KMP算法是一种字符串匹配算法&#xff0c;用于匹配模式串P在文本串S中出现的所有位置。 例如S“ababac”,P"aba",那么出现的所有位置是1 3 KMP算法将原本O&#xff08;n^2&#xff09;的字符串匹配算法优化到了O&#xff08;n&#xff09;&#xff0c;其精…

MySQL使用C语言连接

要使用C语言连接mysql&#xff0c;需要使用mysql官网提供的库&#xff0c;大家可以去MySQL官网下载。 1.引入库 1.选择Download Archivs 因为我们要连接的是C语言&#xff0c;所以选择Connector/C。 选择合适的版本下载&#xff0c;我这里 下载完之后&#xff0c;我们使用rz命…

AtCoder Beginner Contest 347 (ABCDEF题)视频讲解

A - Divisible Problem Statement You are given positive integers N N N and K K K, and a sequence of length N N N, A ( A 1 , A 2 , … , A N ) A(A_1,A_2,\ldots,A_N) A(A1​,A2​,…,AN​). Extract all elements of A A A that are multiples of K K K, divi…

鸿蒙HarmonyOS应用开发之HID DDK开发指导

场景介绍 HID DDK&#xff08;HID Driver Develop Kit&#xff09;是为开发者提供的HID设备驱动程序开发套件&#xff0c;支持开发者基于用户态&#xff0c;在应用层开发HID设备驱动。提供了一系列主机侧访问设备的接口&#xff0c;包括创建设备、向设备发送事件、销毁设备。 …

腾讯云2核4G服务器优惠价格165元一年,限制500GB月流量

腾讯云轻量2核4G5M服务器租用价格165元1年、252元15个月、三年900元&#xff0c;配置为轻量2核4G5M、5M带宽、60GB SSD盘、500GB月流量、上海/广州/北京&#xff0c;腾讯云优惠活动 yunfuwuqiba.com/go/txy 腾讯云轻量2核4G5M服务器租用价格 腾讯云&#xff1a;轻量应用服务器1…

SpringBoot + Vue3邮件验证码功能的实现

后端 SpringBootmavenmysqlIDEA 后端负责编写邮件发送的接口逻辑&#xff0c;具体流程如下: 引入相关依赖配置邮箱信息编写邮件发送服务接口OK 引入依赖 <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail --> <dependen…

基于FreeRTOS系统的STM32简易遥控器设计

项目说明 该项目是一个基于FreeRTOS系统的Stm32遥控器设计。使用该项目主要是自己学习FreeRTOS的使用&#xff0c;以及模块化编程的思想。这个项目应该长期会有更新。 项目开源 github:https://github.com/snqx-lqh/Stm32RemoteControl gitee:https://gitee.com/snqx-lqh/S…

conda 创建 python3.10.12 环境

conda 创建 python3.10.12 环境 介绍使用前置条件&#xff1a;安装 conda配置环境变量验证 Conda 安装结果创建环境&#xff1a;python激活 Anaconda 环境 验证 Python 版本。 介绍 Conda是一个开源的包管理和环境管理系统&#xff0c;由Continuum Analytics公司开发。它可以安…

【InternLM 实战营第二期笔记】InternLM1.8B浦语大模型趣味 Demo

体验环境 平台&#xff1a;InternStudio GPU&#xff1a;10% 配置基础环境 studio-conda -o internlm-base -t demo 与 studio-conda 等效的配置方案 conda create -n demo python3.10 -y conda activate demo conda install pytorch2.0.1 torchvision0.15.2 torchaudio2…

使用MySQL和PHP创建一个公告板

目录 一、创建表 二、制作首页&#xff08;创建主题以及显示列表&#xff09; 三、制作各个主题的页面&#xff08;输入回帖和显示列表&#xff09; 四、制作消息的查询界面 五、制作读取数据库信息的原始文件 六、制作数据重置页面 七、效果图 八、问题 1、目前无法处…

轻量应用服务器16核32G28M腾讯云租用优惠价格4224元15个月

腾讯云16核32G服务器租用价格4224元15个月&#xff0c;买一年送3个月&#xff0c;配置为&#xff1a;轻量16核32G28M、380GB SSD盘、6000GB月流量、28M带宽&#xff0c;腾讯云优惠活动 yunfuwuqiba.com/go/txy 活动链接打开如下图&#xff1a; 腾讯云16核32G服务器租用价格 腾讯…

三栏布局——面试/笔试题

目录 三栏布局(两端指定宽度&#xff0c;中间自适应)三栏布局(平均分布) 三栏布局(两端指定宽度&#xff0c;中间自适应) 只介绍简单的写法&#xff0c;圣杯布局之类的比较复杂&#xff0c;实际上越简单越好&#xff0c;所以复杂的就不介绍了 flex布局 <!DOCTYPE html>…

vultr ubuntu 服务器远程桌面安装及连接

一. 概述 vultr 上开启一个linux服务器&#xff0c;都是以终端形式给出的&#xff0c;默认不带 ui 桌面的&#xff0c;那其实对于想使用服务器上浏览器时的情形不是很好。那有没有方法在远程服务器安装桌面&#xff0c;然后原程使用呢&#xff1f;至少ubuntu的服务器是有的&am…