当前位置: 首页 > news >正文

el-upload上传图片和视频,支持预览和删除

话不多说, 直接上代码:

视图层:

        <div class="contentDetail"><div class="contentItem"><div style="margin-top:5px;" class="label csAttachment">客服上传图片:</div><el-upload:auto-upload="false":limit="10":on-change="fileChange":on-remove="handleRemoveImg":file-list="csImages"action="#"accept=".jpg,.jpeg,.png"list-type="picture-card"><i slot="default" class="el-icon-plus"></i><div slot="file" slot-scope="{ file }"><img :src="file.url" class="el-upload-list__item-thumbnail" alt="" /><div 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="handleRemoveImg(file)"><i class="el-icon-delete"></i></span></div></div></el-upload></div></div><div class="contentDetail"><div class="contentItem"><div class="label csAttachment">客服上传视频:</div><el-upload:auto-upload="false":limit="3":on-change="changeUploadVideo":file-list="csVideos"class="avatar-uploader"action="#"list-type="picture-card"><i slot="default" class="el-icon-plus"></i><div slot="file" slot-scope="{ file }"><video:src="file.url":style="{width: csVideos.length > 0 ? '200px' : 0,height: csVideos.length > 0 ? '120px' : 0}"class="video-avatar"controls="controls"><span>您的浏览器不支持视频播放</span></video><div class="el-upload-list__item-actions" style="z-index:101;height:50px;"><span class="el-upload-list__item-delete" @click="handleRemoveVideo(file)"><i class="el-icon-delete"></i></span></div></div></el-upload></div></div>

逻辑层:

// 监听附件相关数据 
watch: {// 新增图片fileList: {async handler(newList) {this.fileData.imgFiles = []if (newList.length) {let fileObj = {}await newList.map(file => {// 上传的文件流转为base64格式if (file.raw) {getBase64File(file.raw).then(res => {fileObj = {fileName: file.name,fileBase64: res}this.fileData.imgFiles.push(fileObj)})} else {fileObj = {fileBase64: file.fileBase64,fileName: file.name,type: file.type}this.fileData.imgFiles.push(fileObj)}})}}},// 删除已上传图片时newImgList: {handler: function(list) {let obj = {fileBase64: '',fileName: '',type: ''}list.map(file => {obj = {fileBase64: file.fileBase64,fileName: file.name,type: file.type}})this.fileData.imgFiles.push(obj)}},//添加视频videoList: {async handler(newList) {this.fileData.videoFiles = []if (newList.length) {let fileObj = {}await newList.map(file => {// 上传的文件流转为base64格式if (file.raw) {getBase64File(file.raw).then(res => {fileObj = {fileName: file.name,fileBase64: res}this.fileData.videoFiles.push(fileObj)})} else {fileObj = {fileBase64: file.fileBase64,fileName: file.name,type: file.type}this.fileData.videoFiles.push(fileObj)}})}}},// 删除已上传视频时newVideoList: {handler: function(list) {let obj = {fileBase64: '',fileName: '',type: ''}list.map(file => {obj = {fileBase64: file.fileBase64,fileName: file.name,type: file.type}})this.fileData.videoFiles.push(obj)}}},  // 添加图片文件fileChange(file, fileList) {this.fileList = fileListthis.fileList.map((item, index) => {const fileSize = item.size / 1024 / 1024if (fileSize > 20) {this.$message.error('单个附件大小不能超过20M')this.fileList.splice(index, 1)}})setTimeout(() => {this.editFile('image')}, 1000)},// 添加视频文件changeUploadVideo(file, fileList) {const fileSize = file.size / 1024 / 1024 <= 50if (['video/mp4', 'video/ogg', 'video/flv', 'video/avi', 'video/wmv', 'video/rmvb', 'video/mov'].indexOf(file.raw.type) == -1 // 控制格式) {this.$message.error('请上传正确的视频格式')return false}if (!fileSize) {this.$message.error('视频大小不能超过50MB')return false}this.videoList = fileListsetTimeout(() => {this.editFile('video')}, 1000)},// 移除图片文件handleRemoveImg(file) {this.fileList.map((item, index) => {if (item.name === file.name) {// 回显图片时if (item.type === 2) {item.type = 1 // 2 保留 1 删除this.newImgList = this.fileList.splice(index, 1)setTimeout(() => {this.editFile('image')}, 500)} else {// 新增图片时this.fileList.splice(index, 1)}}})},// 移除视频文件handleRemoveVideo(file) {this.videoList.map((item, index) => {if (item.name === file.name) {// 回显视频时if (item.type === 2) {item.type = 1 // 2 保留 1 删除this.newVideoList = this.videoList.splice(index, 1)setTimeout(() => {this.editFile('video')}, 500)} else {// 新增视频时this.videoList.splice(index, 1)}}})},// 预览图片handlePictureCardPreview(file) {this.dialogImageUrl = file.urlthis.$alert(`<img src="${this.dialogImageUrl}" width="100%">`, {dangerouslyUseHTMLString: true,callback: () => {}})},// 编辑附件editFile(type) {const params = {imgFiles: this.fileData.imgFiles,videoFiles: this.fileData.videoFiles,csClass: this.summaryDetail.csClassIds[this.summaryDetail.csClassIds.length - 1],csFeedbackDescribe: this.summaryDetail.csFeedbackDescribe,id: this.summaryDetail.id,role: 1,appPhone: this.summaryDetail.appPhone,sn: this.summaryDetail.sn,qrCode: this.summaryDetail.qrCode,iscallBack: 1 // 是否编辑回电  1否 2是}this.$confirm('确认修改?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {this.loading = trueaddSummary(params) // 后端接口.then(res => {if (res.code === 0) {this.getSummaryList(this.activeName)this.$message.success(res.msg)}}).catch(() => {this.loading = false// 添加修改失败,恢复原有数据if (type === 'image') {this.csImages = handleFileFormat(this.summaryDetail.csImgFiles)} else {this.csVideos = handleFileFormat(this.summaryDetail.csVideoFiles)}})}).catch(() => {// 取消添加修改,恢复原有数据if (type === 'image') {this.csImages = handleFileFormat(this.summaryDetail.csImgFiles)} else {this.csVideos = handleFileFormat(this.summaryDetail.csVideoFiles)}})}

上传附件没有使用单独的上传接口,是调用添加记录接口时,统一传参保存。添加接口请求成功后再回显。

因为我们的需求是在详情页面也能编辑图片和视频,所以加了`type`字段,1代表删除,2代表保留,添加的话就不传。如果你们的需求没有在详情编辑的功能,相关的逻辑可以不用管。

添加失败或取消添加时,恢复原有数据。

视频的时候需要注意:video标签的层级比较高,鼠标hover时上面的删除图标显示不出来,手动修改它们的`z-index`,比如:

 

 删除图标的容器宽度也修改下,否则会覆盖视频播放按钮。

样式设置:

/deep/ .el-upload--picture-card {width: 80px;height: 80px;}/deep/ .el-upload-list__item {width: 80px;height: 80px;}.avatar-uploader {/deep/ .el-upload--picture-card {display: inline-block;width: 200px;height: 120px;}/deep/ .el-upload-list__item {display: inline-block;width: 200px;height: 120px;}}video {display: inline-block;position: relative;z-index: 100;}/deep/ .el-icon-plus {position: relative;top: -35%;}.avatar-uploader {/deep/ .el-icon-plus {position: relative;top: -6%;}}

上传前: 

 上传后:

 

相关文章:

el-upload上传图片和视频,支持预览和删除

话不多说&#xff0c; 直接上代码&#xff1a; 视图层&#xff1a; <div class"contentDetail"><div class"contentItem"><div style"margin-top:5px;" class"label csAttachment">客服上传图片:</div><el…...

clickhouse MPPDB数据库 运维实用SQL总结III

文章目录 CH问题处理使用remote函数报URL "xxxx:9000" is not allowed in configuration fileclickhouse MPPDB数据库 运维实用SQL总结 clickhouse MPPDB数据库 运维实用SQL总结II clickhouse MPPDB数据库 运维实用SQL总结III CH server相关的配置参见 : clickhous…...

ARM和MIPS的区别

ARM和MIPS的区别主要有以下几方面&#xff1a; 指令集&#xff1a;ARM支持32位和64位指令&#xff0c;而MIPS同时支持32位和64位指令。除法器&#xff1a;MIPS有专门的除法器&#xff0c;可以执行除法指令&#xff0c;而ARM没有。寄存器&#xff1a;MIPS的内核寄存器比ARM多一…...

TypeScript -- 类

文章目录 TypeScript -- 类TS -- 类的概念创建一个简单的ts类继承 public / private / protected-- 公共/私有/受保护的public -- 公共private -- 私有的protected -- 受保护的 其他特性readonly -- 只读属性静态属性 -- static修饰ts的getter /setter抽象类abstract TypeScrip…...

【LeetCode】124.二叉树中的最大路径和

题目 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点 root &…...

Linux命令总结

1.目录相关命令 绝对路径&#xff1a; 如/etc/init.d当前目录和上层目录&#xff1a; ./ …/主目录&#xff1a; ~/切换目录&#xff1a; c 2.进程相关命令 查看当前进程&#xff1a; ps ps -ef&#xff08;system v 输出&#xff09;ps -aux bsd 格式输出ps -ef|grep pid 执…...

SpringBoot临时属性设置

在Spring Boot中&#xff0c;可以通过设置临时属性来覆盖应用程序中定义的属性。这在某些情况下很有用&#xff0c;例如在命令行中指定配置参数或在测试环境中覆盖默认值。 你可以使用--&#xff08;双破折号&#xff09;语法来设置临时属性。以下是一些示例&#xff1a; 1. …...

【Python小知识】如何解决代理IP在多线程环境下的并发问题?

前言 在多线程环境下&#xff0c;使用代理IP可能会出现并发问题。具体而言&#xff0c;多个线程可能同时使用同一个代理IP&#xff0c;导致代理IP被封禁或无法访问。为了解决这个问题&#xff0c;我们需要使用一个代理IP池来管理可用的代理IP&#xff0c;并在多线程环境下动态…...

redis常见面试汇总

目录 Redis 适合的场景 Redis 不适合的场景 3、Redis 有哪些常见的功能&#xff1f; 什么是缓存穿透&#xff1f;怎么解决&#xff1f; 什么是缓存雪崩&#xff1f;该如何解决&#xff1f; 参考文献&#xff1a; Redis 适合的场景 缓存&#xff1a;减轻 MySQL 的查询压力…...

子数组的解释与专题

子数组&#xff1a;指在一个数组中&#xff0c;选择一些连续的元素组成的新数组。 例题一&#xff1a;6900. 统计完全子数组的数目 给你一个由 正 整数组成的数组 nums 。 如果数组中的某个子数组满足下述条件&#xff0c;则称之为 完全子数组 &#xff1a; 子数组中 不同 …...

PHP: 开发入门macOS系统下的安装和配置

安装Homebrew 安装 ~~友情提示&#xff1a;这个命令对网络有要求&#xff0c;可能需要翻墙或者用你的手机热点试试&#xff0c;或者把DNS换成&#xff08;114.114.114.114 和 8.8.8.8&#xff09; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebr…...

在CentOS下安装docker

1&#xff09;在Cent OS安装docker先有一个Cent OS 7.6系统 这个很重要&#xff0c;不同版本按照的时候是不一样的。 2&#xff09;查看CentOS版本 cat /etc/redhat-releas 3&#xff09;用root账户登录进去配置国内yum源 wget -O /etc/yum.repos.d/CentOS-Base.repo http:…...

[JavaWeb]SQL介绍-DQL查询数据

SQL介绍-DQL查询数据 一.基础查询二.条件查询三.排序查询1.聚合函数2.分组查询 四.分页查询 DQL查询基础的语法结构如下&#xff1a; SELECT字段列表 FROM表名列表 WHERE条件列表 GROUP BY分组字段 HAVING分组后条件 ORDER BY排序字段 LIMIT分页限定一.基础查询 说明语法查询…...

[containerd] 在Windows上使用IDEA远程调试containerd, ctr, containerd-shim

文章目录 1. containerd安装2. 源码编译3. 验证编译的二进制文件是否含有调试需要的信息3.1. objdump工具验证3.2. file工具验证3.3. dlv工具验证 4. debug 1. containerd安装 [Ubuntu 22.04] 安装containerd 2. 源码编译 主要步骤如下&#xff1a; 1、从github下载containe…...

Verilog语法学习——LV4_移位运算与乘法

LV4_移位运算与乘法 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 题目描述&#xff1a; 已知d为一个8位数&#xff0c;请在每个时钟周期分别输出该数乘1/…...

打卡力扣题目九

#左耳听风 ARST 打卡活动重启# 目录 一、问题 二、解题方法一 三、解题方法二 四、两种方法的区别 关于 ARTS 的释义 —— 每周完成一个 ARTS&#xff1a; ● Algorithm: 每周至少做一个 LeetCode 的算法题 ● Review: 阅读并点评至少一篇英文技术文章 ● Tips: 学习至少一个…...

Python零基础入门(九)——函数,类和对象

系列文章目录 个人简介&#xff1a;机电专业在读研究生&#xff0c;CSDN内容合伙人&#xff0c;博主个人首页 Python入门专栏&#xff1a;《Python入门》欢迎阅读&#xff0c;一起进步&#xff01;&#x1f31f;&#x1f31f;&#x1f31f; 码字不易&#xff0c;如果觉得文章不…...

在linux上面部署activemq

1、下载 网址&#xff1a;ActiveMQ 注意&#xff1a;新版本5.17起 要求jdk11, 5.16兼容jdk8, 所以&#xff0c;确保已经安装 java11 或以上的版本 这里安装较新版&#xff1a;5.18.2&#xff0c;已经安装了java17 如何安装jdk17,请详见我的另一篇文章&#xff1a;linux…...

mysql的sql语句优化方法面试题总结

mysql的sql语句优化方法面试题总结 不要写一些没有意义的查询&#xff0c;如需要生成一个空表结构&#xff1a; select col1,col2 into #t from t where 10 这类代码不会返回任何结果集&#xff0c;但是会消耗系统资源的&#xff0c;应改成这样&#xff1a; create table #t…...

小程序 获取用户头像、昵称、手机号的组件封装(最新版)

在父组件引入该组件 <!-- 授权信息 --><auth-mes showModal"{{showModal}}" idautnMes bind:onConfirm"onConfirm"></auth-mes> 子组件详细代码为: authMes.wxml <!-- components/authMes/authMes.wxml --> <van-popup show…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...

高分辨率图像合成归一化流扩展

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 1 摘要 我们提出了STARFlow&#xff0c;一种基于归一化流的可扩展生成模型&#xff0c;它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流&#xff08;TARFlow&am…...