优化VUE Element UI的上传插件

默认ElmentUI的文件列表只有一个删除按钮,我需要加预览、下载、编辑等,就需要优化显示结果。

优化后没用上传进度条,又加了一个进度条效果

代码

<template><div><el-uploadclass="upload-demo"action="/":file-list="fileList":disabled="isUpLoading":before-upload="beforeUpload":http-request="handleHttpRequest":on-remove="handleRemoveFile":on-progress="handleLoading":on-success="handleUploadSuccess"><el-button size="small" :loading="isUpLoading" type="primary">{{this.isUpLoading?"附件上传中...":"点击上传"}} </el-button><div slot="tip" class="el-upload__tip">(建议上传附件大小在5M以内)</div></el-upload><div id="file-list"><el-progress v-if="isUpLoading" :percentage="uploadingProgress"></el-progress><div v-for="(file,index) in fileList" :key="file.fileIdentifier" style="display: flex;justify-content: space-between;line-height: 25px;"><div>{{index+1}}、{{file.name}} </div><div style="padding-right: 20px;"><a href="javascript:void(0)" style="cursor:pointer;" @click="fileOption(file,'down')">下载</a><a href="javascript:void(0)" v-if = "officeFileType.includes(file.wjhz.toLowerCase())" style="margin-left: 10px;cursor:pointer;"  @click="fileOption(file,'show')">查看</a><a href="javascript:void(0)" v-if = "officeFileType.includes(file.wjhz.toLowerCase())" style="margin-left: 10px;cursor: pointer;" @click="fileOption(file,'edit')">编辑</a><a href="javascript:void(0)" style="margin-left: 10px;cursor: pointer;" @click="fileOption(file,'del')">删除</a></div></div></div></div>
</template><style lang="scss" scoped>
::v-deep .el-upload-list{display: none;
}
</style><script>
import md5 from "@/api/file/md5";
import { taskInfo, initTask, preSignUrl, merge, del, getFileList} from '@/api/file/api';
import Queue from 'promise-queue-plus';
import axios from 'axios'
import VXETable from 'vxe-table'
import { changeUserStatus } from '@/api/system/user'export default {name: 'upload-page',props: {// 文件类型fjlxdm: {required: true,type: String},// 业务主建ywbs: {required: true,type: String},},created(){this.initData();},data() {return {fileUploadChunkQueue:{},lastUploadedSize:0,// 上次断点续传时上传的总大小uploadedSize:0,// 已上传的大小totalSize:0,// 文件总大小startMs:'',// 开始上传的时间taskRecord:{},options:{},fileList:[],officeFileType:['.ppt', '.pptx', '.doc', '.docx', '.xls', '.xlsx','.pdf'],isUpLoading:false,uploadingProgress:0,uploadTime:null,}},methods: {handleLoading(event, file, fileList){if(this.uploadTime!=null){clearInterval(this.uploadTime);this.uploadTime=null;}this.uploadingProgress=parseFloat(event.percent);},fileOption(file,type){if(type=="down"){//下载window.open(file.url, "_blank");return;}if(type=="show"){//查看const { href } = this.$router.resolve({name: 'office',query: {fjxxbs: file.fjxxbs,viewUrl: file.viewUrl,ot: 'detail'}})window.open(href, '_blank')return;}if(type=="edit"){//编辑const { href } = this.$router.resolve({name: 'office',query: {fjxxbs: file.fjxxbs,viewUrl: file.viewUrl,ot: 'edit'}})window.open(href, '_blank')return;}if(type=="del"){//删除this.$confirm('确认删除该附件?',"警告",{confirmButtonText: "确定",cancelButtonText: "取消",type: "warning",}).then( () => {del(file.fjxxbs).then(ret => {const index = this.fileList.findIndex((item) => item.fjxxbs === file.fjxxbs);this.fileList.splice(index, 1);this.msgSuccess("删除成功");});})return;}},/*** 获取附件列表*/initData(){this.uploadingProgress=100;getFileList(this.ywbs,this.fjlxdm).then(ret => {this.fileList = ret.data;setTimeout(()=>{this.isUpLoading=false;},500);})},/*** 获取一个上传任务,没有则初始化一个*/async getTaskInfo(file){let task;const identifier = await md5(file)const { code, data, msg } = await taskInfo(identifier,this.ywbs,this.fjlxdm);if (code === 200) {task = dataif (task===undefined) {const initTaskData = {identifier,fileName: file.name,totalSize: file.size,chunkSize: 5 * 1024 * 1024,ywbs:this.ywbs,fjlxdm:this.fjlxdm}const { code, data, msg } = await initTask(initTaskData)if (code === 200) {task = data} else {this.$notify({title:'提示',message: '文件上传错误',type: 'error',duration: 2000})}}} else {this.$notify({title:'提示',message: '文件上传错误',type: 'error',duration: 2000})}return task},// 获取从开始上传到现在的平均速度(byte/s)getSpeed(){// 已上传的总大小 - 上次上传的总大小(断点续传)= 本次上传的总大小(byte)const intervalSize = this.uploadedSize - this.lastUploadedSizeconst nowMs = new Date().getTime()// 时间间隔(s)const intervalTime = (nowMs - this.startMs) / 1000return intervalSize / intervalTime},async uploadNext(partNumber){const {chunkSize,fileIdentifier} = this.taskRecord;const start = new Number(chunkSize) * (partNumber - 1)const end = start + new Number(chunkSize)const blob = this.options.file.slice(start, end)const { code, data, msg } = await preSignUrl({ identifier: fileIdentifier, partNumber: partNumber , ywbs:this.ywbs , fjlxdm:this.fjlxdm} )if (code === 200 && data) {await axios.request({url: data,method: 'PUT',data: blob,headers: {'Content-Type': 'application/octet-stream'}})return Promise.resolve({ partNumber: partNumber, uploadedSize: blob.size })}return Promise.reject(`分片${partNumber}, 获取上传地址失败`)},/*** 更新上传进度* @param increment 为已上传的进度增加的字节量*/updateProcess(increment){increment = new Number(increment)const { onProgress } = this.optionslet factor = 1000; // 每次增加1000 bytelet from = 0;// 通过循环一点一点的增加进度while (from <= increment) {from += factorthis.uploadedSize += factorconst percent = Math.round(this.uploadedSize / this.totalSize * 100).toFixed(2);onProgress({percent: percent})}const speed = this.getSpeed();const remainingTime = speed != 0 ? Math.ceil((this.totalSize - this.uploadedSize) / speed) + 's' : '未知'console.log('剩余大小:', (this.totalSize - this.uploadedSize) / 1024 / 1024, 'mb');console.log('当前速度:', (speed / 1024 / 1024).toFixed(2), 'mbps');console.log('预计完成:', remainingTime);},handleUpload(file, taskRecord){this.lastUploadedSize = 0; // 上次断点续传时上传的总大小this.uploadedSize = 0 // 已上传的大小this.totalSize = file.size || 0 // 文件总大小this.startMs = new Date().getTime(); // 开始上传的时间this.taskRecord = taskRecord;const { exitPartList, chunkNum} = taskRecordreturn new Promise(resolve => {const failArr = [];const queue = Queue(5, {"retry": 3,               //Number of retries"retryIsJump": false,     //retry now?"workReject": function(reason,queue){failArr.push(reason)},"queueEnd": function(queue){resolve(failArr);}})this.fileUploadChunkQueue[file.uid] = queuefor (let partNumber = 1; partNumber <= chunkNum; partNumber++) {const exitPart = (exitPartList || []).find(exitPart => exitPart.partNumber == partNumber)if (exitPart) {// 分片已上传完成,累计到上传完成的总额中,同时记录一下上次断点上传的大小,用于计算上传速度this.lastUploadedSize += new Number(exitPart.size)this.updateProcess(exitPart.size)} else {queue.push(() => this.uploadNext(partNumber).then(res => {// 单片文件上传完成再更新上传进度this.updateProcess(res.uploadedSize)}))}}if (queue.getLength() == 0) {// 所有分片都上传完,但未合并,直接return出去,进行合并操作resolve(failArr);return;}queue.start()})},async handleHttpRequest(options){this.options = options;const file = options.fileconst task = await this.getTaskInfo(file)const that = this;if (task) {const { finished, path, taskRecord } = taskconst {fileIdentifier,fjxxbs } = taskRecordif (finished) {return {fileIdentifier,fjxxbs}} else {const errorList = await this.handleUpload(file, taskRecord)if (errorList.length > 0) {this.$notify({title:'文件上传错误',message: '部分分片上传失败,请尝试重新上传文件',type: 'error',duration: 2000})return;}const { code, data, msg } = await merge(fileIdentifier,that.ywbs,that.fjlxdm)if (code === 200) {return {fileIdentifier,fjxxbs};} else {this.$notify({title:'提示',message: '文件上传错误',type: 'error',duration: 2000})}}} else {this.$notify({title:'文件上传错误',message: '获取上传任务失败',type: 'error',duration: 2000})}},/*** 重复上传* @param {} file*/beforeUpload(file){return new Promise((resolve, reject) => {md5(file).then(result => {const index = this.fileList.findIndex((item) => item.fileIdentifier === result);if(index==-1){this.isUpLoading=true;this.uploadingProgress=0;this.uploadTime=setInterval(()=>{this.uploadingProgress+=1;},500)return resolve(true);}else{return reject(false);}})});},handleRemoveFile(uploadFile, uploadFiles){const queueObject = this.fileUploadChunkQueue[uploadFile.uid]if (queueObject) {queueObject.stop()this.fileUploadChunkQueue[uploadFile.uid] = undefined;}if(uploadFile.fjxxbs != undefined){del(uploadFile.fjxxbs).then(ret => {const index = this.fileList.findIndex((item) => item.fjxxbs === uploadFile.fjxxbs);this.fileList.splice(index, 1);})}},/*** 上传成功*/handleUploadSuccess(res, file, fileList) {// file.fileIdentifier = res.fileIdentifier;// file.fjxxbs = res.fjxxbs;// this.fileList.push(file);this.initData();}}
}</script>

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

09_瑞萨GUI(LVGL)移植实战教程之拓展练习

本系列教程配套出有视频教程&#xff0c;观看地址&#xff1a;https://www.bilibili.com/video/BV1gV4y1e7Sg 9. 拓展练习 本节安排三个实验检验学习成果&#xff0c;实验示例源码在资料包的这个位置&#xff1a; DShanMCU-RA6M5配套学习资料\2_配套源码\02_瑞萨电子MCU GUI(…

《Tree of Thoughts: Deliberate Problem Solving with Large Language Models》中文翻译

《Tree of Thoughts: Deliberate Problem Solving with Large Language Models》- 思维树&#xff1a;用大型语言模型有意识地解决问题 论文信息摘要1. 介绍2. 背景3. 思想树&#xff1a;用 LM 有意识地解决问题4. 实验4.1 24 人游戏4.2 创意写作4.3 迷你填字游戏 5. 相关工作6…

基于大规模测量和多任务深度学习的电子鼻系统目标识别、浓度预测和状态判断

Target discrimination, concentration prediction, and status judgment of electronic nose system based on large-scale measurement and multi-task deep learning 摘要 为了实现响应特征的自动提取&#xff0c;简化模型的训练和应用过程&#xff0c;设计了一种双块知识…

【数据结构--二叉树】平衡二叉树

题目描述&#xff1a; 代码实现&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ int TreeHeight(struct TreeNode* root) {if(rootNULL)return 0;//左右子树中大的…

Linux 中的 chpasswd 命令及示例

chpasswd命令用于更改密码,尽管passwd命令也可以执行相同的操作。但它一次更改一个用户的密码,因此对于多个用户,使用chpasswd 。下图显示了passwd命令的使用。使用passwd我们正在更改来宾用户的密码。首先,您必须输入当前签名用户的密码,然后更改任何其他用户的密码。必须…

Java认识异常(超级详细)

目录 异常的概念和体系结构 异常的概念 异常的体系结构 异常的分类 1.编译时异常 2.运行时异常 异常的处理 防御式编程 LBYL EAFP 异常的抛出 异常的捕获 异常声明throws try-catch捕获并处理 finally 异常的处理流程 异常的概念和体系结构 异常的概念 在Java中…

RabbtiMQ的安装与在Springboot中的使用!!!

一、安装Erlang与Rabbitmq 安装教程本教程是在centos8下试验的&#xff0c;其实linux系统的都差不多RabbitMQ官方&#xff1a;Messaging that just works — RabbitMQRabbitMQ是开源AMQP实现&#xff0c;服务器端用Erlang语言编写&#xff0c;Python、Ruby、 NET、Java、JMS、c…

二十、MySQL多表关系

1、概述 在项目开发中&#xff0c;在进行数据库表结构设计时&#xff0c;会根据业务需求以及业务模块之间的关系&#xff0c;分析并设计表结构&#xff0c;由于业务之间相互关联&#xff0c;所以各个表结构之间也存在着各种对应关系 2、多表关系分类 &#xff08;1&#xff0…

你用过 Maven Shade 插件吗?

文章首发地址 Maven Shade插件是Maven构建工具的一个插件&#xff0c;用于构建可执行的、可独立运行的JAR包。它解决了依赖冲突的问题&#xff0c;将项目及其所有依赖&#xff08;包括传递依赖&#xff09;合并到一个JAR文件中。 下面是对Maven Shade插件的一些详解&#xff…

202330读书笔记|《中国百年文学经典桥梁书(全8册)》——故乡,匆匆,春,背影,白鹅,百草园

202330读书笔记|《中国百年文学经典桥梁书&#xff08;全8册&#xff09;》——故乡&#xff0c;匆匆&#xff0c;春&#xff0c;背影&#xff0c;白鹅&#xff0c;百草园 《中国百年文学经典桥梁书&#xff08;全8册&#xff09;》作者朱自清&#xff0c;鲁迅等。很多都是小学…

从软件工程师角度聊聊 Kubernetes

作为软件工程师&#xff0c;我们应该熟悉 K8s&#xff0c;尽管它有点像 DevOps&#xff0c;但它能让我们更好地了解幕后发生的事情&#xff0c;让我们与部署工作更密切相关&#xff0c;更有责任感。本文将从软件工程师的角度探讨 Kubernetes (K8s)&#xff0c;我们将介绍其动机…

无涯教程-JavaScript - IMSECH函数

描述 IMSECH函数以x yi或x yj文本格式返回复数的双曲正割。复数的双曲正割被定义为双曲余弦的倒数,即 六(z) 1/cosh(z) 语法 IMSECH (inumber)争论 Argument描述Required/OptionalInumberA complex number for which you want the hyperbolic secant.Required Notes Ex…

zookeeper/HA集群配置

1.zookeep配置 1.1 安装4台虚拟机 &#xff08;1&#xff09;按照如下设置准备四台虚拟机&#xff0c;其中三台作为zookeeper&#xff0c;配置每台机器相应的IP&#xff0c;hostname&#xff0c;下载vim&#xff0c;ntpdate配置定时器定时更新时间&#xff0c;psmisc&#xff…

linux 进程隔离Namespace 学习

一、linux namespace 介绍 1.1、概念 Linux Namespace是Linux内核提供的一种机制&#xff0c;它用于隔离不同进程的资源视图&#xff0c;使得每个进程都拥有独立的资源空间&#xff0c;从而实现进程之间的隔离和资源管理。 Linux Namespace的设计目标是为了解决多个进程之间…

Android Jetpack架构组件库:Hilt

一、开发者官网关于Hilt库使用链接如下 使用 Hilt 实现依赖项注入 Hilt版本说明 二、工程目录图 请点击下面工程名称&#xff0c;跳转到代码的仓库页面&#xff0c;将工程 下载下来 Demo Code 里有详细的注释 代码&#xff1a;LearnJetpack-hilt&#xff1a;hilt版本2.48 代…

国标GB28181协议视频平台EasyGBS国标平台设备播放断流现象的排查分析及解决

EasyGBS平台基于GB28181国标协议&#xff0c;支持多路设备接入&#xff0c;并对多平台、多终端分发出RTSP、RTMP、FLV、HLS、WebRTC等多种格式的视频流。平台可为大数据等综合性监管平台提供极强的视频能力&#xff0c;已经在大量的项目中落地应用&#xff0c;如明厨亮灶、平安…

【C++心愿便利店】No.5---构造函数和析构函数

文章目录 前言一、类的6个默认成员函数二、构造函数三、析构函数 前言 &#x1f467;个人主页&#xff1a;小沈YO. &#x1f61a;小编介绍&#xff1a;欢迎来到我的乱七八糟小星球&#x1f31d; &#x1f4cb;专栏&#xff1a;C 心愿便利店 &#x1f511;本章内容&#xff1a;类…

20230904 QT客户端服务器搭建聊天室

Ser cpp#include "app.h" #include "ui_app.h"APP::APP(QWidget *parent):QWidget(parent),ui(new Ui::APP) {ui->setupUi(this);this->resize(550,400);ui->Line->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中ui->Line->se…

智能井盖传感器:高效守护城市道路安全

近年来&#xff0c;井盖出问题导致事故的报道时有发生&#xff0c;但却容易被公众所忽视。井盖作为城市基础设施的一部分&#xff0c;主要用于保护下方的供水管道、下水道以及电信线缆等。然而&#xff0c;由于长时间使用、缺乏维护、设计不合理等原因&#xff0c;井盖出现问题…

C语言——程序环境和预处理(再也不用担心会忘记预处理的知识)

了解程序环境和预处理 前言&#xff1a;一、程序环境二、编译链接2.1 翻译环境2.2 编译的几个阶段2.3 运行环境 三、预处理3.1 预定义符号3.2. #define的使用3.2.1 #define 定义标识符3.2.2 #define 定义宏3.2.3 #define 替换规则3.2.4 #和##的用途3.2.5 带副作用的宏参数3.2.6…