

默认ElmentUI的文件列表只有一个删除按钮,我需要加预览、下载、编辑等,就需要优化显示结果。
优化后没用上传进度条,又加了一个进度条效果
代码
- <template>
- <div>
- <el-upload
- class="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 = data
- if (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.lastUploadedSize
- const nowMs = new Date().getTime()
- // 时间间隔(s)
- const intervalTime = (nowMs - this.startMs) / 1000
- return 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.options
- let factor = 1000; // 每次增加1000 byte
- let from = 0;
- // 通过循环一点一点的增加进度
- while (from <= increment) {
- from += factor
- this.uploadedSize += factor
- const 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} = taskRecord
-
- return 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] = queue
- for (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.file
- const task = await this.getTaskInfo(file)
- const that = this;
-
- if (task) {
- const { finished, path, taskRecord } = task
- const {fileIdentifier,fjxxbs } = taskRecord
- if (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>