| | |
| | | :extension="extension" |
| | | :file-category="fileCategory" |
| | | > |
| | | <div class="uploader-file-progress" :class="progressingClass" :style="progressStyle"></div> |
| | | <div |
| | | class="uploader-file-progress" |
| | | :class="progressingClass" |
| | | :style="progressStyle" |
| | | ></div> |
| | | <div class="uploader-file-info"> |
| | | <div class="uploader-file-name"> |
| | | <i class="uploader-file-icon" :icon="fileCategory"></i> |
| | | {{file.name}} |
| | | {{ file.name }} |
| | | </div> |
| | | <div class="uploader-file-size">{{formatedSize}}</div> |
| | | <div class="uploader-file-size">{{ formatedSize }}</div> |
| | | <div class="uploader-file-meta"></div> |
| | | <div class="uploader-file-status"> |
| | | <span v-show="status !== 'uploading'">{{statusText}}</span> |
| | | <span v-show="status !== 'uploading'">{{ statusText }}</span> |
| | | <span v-show="status === 'uploading'"> |
| | | <span>{{progressStyle.progress}}</span> |
| | | <em>{{formatedAverageSpeed}}</em> |
| | | <span>{{ progressStyle.progress }}</span> |
| | | <em>{{ formatedAverageSpeed }}</em> |
| | | |
| | | <i> {{formatedTimeRemaining}}</i> |
| | | <i> {{ formatedTimeRemaining }}</i> |
| | | </span> |
| | | </div> |
| | | <div class="uploader-file-actions"> |
| | | <span class="uploader-file-pause" @click="pause"></span> |
| | | <span class="uploader-file-resume" @click="resume">️</span> |
| | | <span class="uploader-file-retry" @click="retry"></span> |
| | | <span class="uploader-file-remove" @click="remove"></span> |
| | | <el-tooltip effect="dark" content="重新上传" placement="bottom"> |
| | | <span class="uploader-file-retry" @click="retry"></span> |
| | | </el-tooltip> |
| | | <el-tooltip effect="dark" content="删除" placement="bottom"> |
| | | <span class="uploader-file-remove" @click="remove"></span> |
| | | </el-tooltip> |
| | | </div> |
| | | </div> |
| | | </slot> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import Uploader from 'simple-uploader.js' |
| | | import events from './common/file-events' |
| | | import { secondsToStr } from './common/utils' |
| | | import Uploader from "simple-uploader.js"; |
| | | import events from "./common/file-events"; |
| | | import { secondsToStr } from "./common/utils"; |
| | | |
| | | const COMPONENT_NAME = 'uploader-file' |
| | | const COMPONENT_NAME = "uploader-file"; |
| | | |
| | | export default { |
| | | name: COMPONENT_NAME, |
| | |
| | | file: { |
| | | type: Object, |
| | | default() { |
| | | return {} |
| | | } |
| | | return {}; |
| | | }, |
| | | }, |
| | | list: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | default: false, |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | |
| | | isComplete: false, |
| | | isUploading: false, |
| | | size: 0, |
| | | formatedSize: '', |
| | | formatedSize: "", |
| | | uploadedSize: 0, |
| | | progress: 0, |
| | | timeRemaining: 0, |
| | | type: '', |
| | | extension: '', |
| | | progressingClass: '' |
| | | } |
| | | type: "", |
| | | extension: "", |
| | | progressingClass: "", |
| | | }; |
| | | }, |
| | | computed: { |
| | | fileCategory() { |
| | | const extension = this.extension |
| | | const isFolder = this.file.isFolder |
| | | let type = isFolder ? 'folder' : 'unknown' |
| | | const categoryMap = this.file.uploader.opts.categoryMap |
| | | const extension = this.extension; |
| | | const isFolder = this.file.isFolder; |
| | | let type = isFolder ? "folder" : "unknown"; |
| | | const categoryMap = this.file.uploader.opts.categoryMap; |
| | | const typeMap = categoryMap || { |
| | | image: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp'], |
| | | video: ['mp4', 'm3u8', 'rmvb', 'avi', 'swf', '3gp', 'mkv', 'flv'], |
| | | audio: ['mp3', 'wav', 'wma', 'ogg', 'aac', 'flac'], |
| | | document: ['doc', 'txt', 'docx', 'pages', 'epub', 'pdf', 'numbers', 'csv', 'xls', 'xlsx', 'keynote', 'ppt', 'pptx'] |
| | | } |
| | | image: ["gif", "jpg", "jpeg", "png", "bmp", "webp"], |
| | | video: ["mp4", "m3u8", "rmvb", "avi", "swf", "3gp", "mkv", "flv"], |
| | | audio: ["mp3", "wav", "wma", "ogg", "aac", "flac"], |
| | | document: [ |
| | | "doc", |
| | | "txt", |
| | | "docx", |
| | | "pages", |
| | | "epub", |
| | | "pdf", |
| | | "numbers", |
| | | "csv", |
| | | "xls", |
| | | "xlsx", |
| | | "keynote", |
| | | "ppt", |
| | | "pptx", |
| | | ], |
| | | }; |
| | | Object.keys(typeMap).forEach((_type) => { |
| | | const extensions = typeMap[_type] |
| | | const extensions = typeMap[_type]; |
| | | if (extensions.indexOf(extension) > -1) { |
| | | type = _type |
| | | type = _type; |
| | | } |
| | | }) |
| | | return type |
| | | }); |
| | | return type; |
| | | }, |
| | | progressStyle() { |
| | | const progress = Math.floor(this.progress * 100) |
| | | const style = `translateX(${Math.floor(progress - 100)}%)` |
| | | const progress = Math.floor(this.progress * 100); |
| | | const style = `translateX(${Math.floor(progress - 100)}%)`; |
| | | return { |
| | | progress: `${progress}%`, |
| | | webkitTransform: style, |
| | | mozTransform: style, |
| | | msTransform: style, |
| | | transform: style |
| | | } |
| | | transform: style, |
| | | }; |
| | | }, |
| | | formatedAverageSpeed() { |
| | | return `${Uploader.utils.formatSize(this.averageSpeed)} / s` |
| | | return `${Uploader.utils.formatSize(this.averageSpeed)} / s`; |
| | | }, |
| | | status() { |
| | | const isUploading = this.isUploading |
| | | const isComplete = this.isComplete |
| | | const isError = this.error |
| | | const paused = this.paused |
| | | const isUploading = this.isUploading; |
| | | const isComplete = this.isComplete; |
| | | const isError = this.error; |
| | | const paused = this.paused; |
| | | if (isComplete) { |
| | | return 'success' |
| | | return "success"; |
| | | } else if (isError) { |
| | | return 'error' |
| | | return "error"; |
| | | } else if (isUploading) { |
| | | return 'uploading' |
| | | return "uploading"; |
| | | } else if (paused) { |
| | | return 'paused' |
| | | return "paused"; |
| | | } else { |
| | | return 'waiting' |
| | | return "waiting"; |
| | | } |
| | | }, |
| | | statusText() { |
| | | const status = this.status |
| | | const fileStatusText = this.file.uploader.fileStatusText |
| | | let txt = status |
| | | if (typeof fileStatusText === 'function') { |
| | | txt = fileStatusText(status, this.response) |
| | | const status = this.status; |
| | | const fileStatusText = this.file.uploader.fileStatusText; |
| | | let txt = status; |
| | | if (typeof fileStatusText === "function") { |
| | | txt = fileStatusText(status, this.response); |
| | | } else { |
| | | txt = fileStatusText[status] |
| | | txt = fileStatusText[status]; |
| | | } |
| | | return txt || status |
| | | return txt || status; |
| | | }, |
| | | formatedTimeRemaining() { |
| | | const timeRemaining = this.timeRemaining |
| | | const file = this.file |
| | | const timeRemaining = this.timeRemaining; |
| | | const file = this.file; |
| | | if (timeRemaining === Number.POSITIVE_INFINITY || timeRemaining === 0) { |
| | | return '' |
| | | return ""; |
| | | } |
| | | let parsedTimeRemaining = secondsToStr(timeRemaining) |
| | | const parseTimeRemaining = file.uploader.opts.parseTimeRemaining |
| | | let parsedTimeRemaining = secondsToStr(timeRemaining); |
| | | const parseTimeRemaining = file.uploader.opts.parseTimeRemaining; |
| | | if (parseTimeRemaining) { |
| | | parsedTimeRemaining = parseTimeRemaining(timeRemaining, parsedTimeRemaining) |
| | | parsedTimeRemaining = parseTimeRemaining( |
| | | timeRemaining, |
| | | parsedTimeRemaining |
| | | ); |
| | | } |
| | | return parsedTimeRemaining |
| | | } |
| | | return parsedTimeRemaining; |
| | | }, |
| | | }, |
| | | watch: { |
| | | status(newStatus, oldStatus) { |
| | | if (oldStatus && newStatus === 'uploading' && oldStatus !== 'uploading') { |
| | | if (oldStatus && newStatus === "uploading" && oldStatus !== "uploading") { |
| | | this.tid = setTimeout(() => { |
| | | this.progressingClass = 'uploader-file-progressing' |
| | | }, 200) |
| | | this.progressingClass = "uploader-file-progressing"; |
| | | }, 200); |
| | | } else { |
| | | clearTimeout(this.tid) |
| | | this.progressingClass = '' |
| | | clearTimeout(this.tid); |
| | | this.progressingClass = ""; |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | methods: { |
| | | _actionCheck() { |
| | | this.paused = this.file.paused |
| | | this.error = this.file.error |
| | | this.isUploading = this.file.isUploading() |
| | | this.paused = this.file.paused; |
| | | this.error = this.file.error; |
| | | this.isUploading = this.file.isUploading(); |
| | | }, |
| | | pause() { |
| | | this.file.pause() |
| | | this._actionCheck() |
| | | this._fileProgress() |
| | | this.file.pause(); |
| | | this._actionCheck(); |
| | | this._fileProgress(); |
| | | }, |
| | | resume() { |
| | | this.file.resume() |
| | | this._actionCheck() |
| | | this.file.resume(); |
| | | this._actionCheck(); |
| | | }, |
| | | remove() { |
| | | this.file.cancel() |
| | | this.file.cancel(); |
| | | }, |
| | | retry() { |
| | | this.file.retry() |
| | | this._actionCheck() |
| | | this.file.retry(); |
| | | this._actionCheck(); |
| | | }, |
| | | processResponse(message) { |
| | | let res = message |
| | | let res = message; |
| | | try { |
| | | res = JSON.parse(message) |
| | | } catch (e) { } |
| | | this.response = res |
| | | res = JSON.parse(message); |
| | | } catch (e) {} |
| | | this.response = res; |
| | | }, |
| | | fileEventsHandler(event, args) { |
| | | const rootFile = args[0] |
| | | const file = args[1] |
| | | const target = this.list ? rootFile : file |
| | | const rootFile = args[0]; |
| | | const file = args[1]; |
| | | const target = this.list ? rootFile : file; |
| | | if (this.file === target) { |
| | | if (this.list && event === 'fileSuccess') { |
| | | this.processResponse(args[2]) |
| | | return |
| | | if (this.list && event === "fileSuccess") { |
| | | this.processResponse(args[2]); |
| | | return; |
| | | } |
| | | this[`_${event}`].apply(this, args) |
| | | this[`_${event}`].apply(this, args); |
| | | } |
| | | }, |
| | | _fileProgress() { |
| | | this.progress = this.file.progress() |
| | | this.averageSpeed = this.file.averageSpeed |
| | | this.currentSpeed = this.file.currentSpeed |
| | | this.timeRemaining = this.file.timeRemaining() |
| | | this.uploadedSize = this.file.sizeUploaded() |
| | | this._actionCheck() |
| | | this.progress = this.file.progress(); |
| | | this.averageSpeed = this.file.averageSpeed; |
| | | this.currentSpeed = this.file.currentSpeed; |
| | | this.timeRemaining = this.file.timeRemaining(); |
| | | this.uploadedSize = this.file.sizeUploaded(); |
| | | this._actionCheck(); |
| | | }, |
| | | _fileSuccess(rootFile, file, message) { |
| | | if (rootFile) { |
| | | this.processResponse(message) |
| | | this.processResponse(message); |
| | | } |
| | | this._fileProgress() |
| | | this.error = false |
| | | this.isComplete = true |
| | | this.isUploading = false |
| | | console.log('rootFile, file, message', rootFile, file, message) |
| | | this._fileProgress(); |
| | | this.error = false; |
| | | this.isComplete = true; |
| | | this.isUploading = false; |
| | | console.log("rootFile, file, message", rootFile, file, message); |
| | | }, |
| | | _fileComplete() { |
| | | this._fileSuccess() |
| | | this._fileSuccess(); |
| | | }, |
| | | _fileError(rootFile, file, message) { |
| | | this._fileProgress() |
| | | console.log('rootFile, file, message', rootFile, file, message) |
| | | this.processResponse(message) |
| | | this.error = true |
| | | this.isComplete = false |
| | | this.isUploading = false |
| | | } |
| | | this._fileProgress(); |
| | | console.log("rootFile, file, message", rootFile, file, message); |
| | | this.processResponse(message); |
| | | this.error = true; |
| | | this.isComplete = false; |
| | | this.isUploading = false; |
| | | }, |
| | | }, |
| | | mounted() { |
| | | const staticProps = ['paused', 'error', 'averageSpeed', 'currentSpeed'] |
| | | const staticProps = ["paused", "error", "averageSpeed", "currentSpeed"]; |
| | | const fnProps = [ |
| | | 'isComplete', |
| | | 'isUploading', |
| | | "isComplete", |
| | | "isUploading", |
| | | { |
| | | key: 'size', |
| | | fn: 'getSize' |
| | | key: "size", |
| | | fn: "getSize", |
| | | }, |
| | | { |
| | | key: 'formatedSize', |
| | | fn: 'getFormatSize' |
| | | key: "formatedSize", |
| | | fn: "getFormatSize", |
| | | }, |
| | | { |
| | | key: 'uploadedSize', |
| | | fn: 'sizeUploaded' |
| | | key: "uploadedSize", |
| | | fn: "sizeUploaded", |
| | | }, |
| | | 'progress', |
| | | 'timeRemaining', |
| | | "progress", |
| | | "timeRemaining", |
| | | { |
| | | key: 'type', |
| | | fn: 'getType' |
| | | key: "type", |
| | | fn: "getType", |
| | | }, |
| | | { |
| | | key: 'extension', |
| | | fn: 'getExtension' |
| | | } |
| | | ] |
| | | staticProps.forEach(prop => { |
| | | this[prop] = this.file[prop] |
| | | }) |
| | | key: "extension", |
| | | fn: "getExtension", |
| | | }, |
| | | ]; |
| | | staticProps.forEach((prop) => { |
| | | this[prop] = this.file[prop]; |
| | | }); |
| | | fnProps.forEach((fnProp) => { |
| | | if (typeof fnProp === 'string') { |
| | | this[fnProp] = this.file[fnProp]() |
| | | if (typeof fnProp === "string") { |
| | | this[fnProp] = this.file[fnProp](); |
| | | } else { |
| | | this[fnProp.key] = this.file[fnProp.fn]() |
| | | this[fnProp.key] = this.file[fnProp.fn](); |
| | | } |
| | | }) |
| | | }); |
| | | |
| | | const handlers = this._handlers = {} |
| | | const handlers = (this._handlers = {}); |
| | | const eventHandler = (event) => { |
| | | handlers[event] = (...args) => { |
| | | this.fileEventsHandler(event, args) |
| | | } |
| | | return handlers[event] |
| | | } |
| | | this.fileEventsHandler(event, args); |
| | | }; |
| | | return handlers[event]; |
| | | }; |
| | | events.forEach((event) => { |
| | | this.file.uploader.on(event, eventHandler(event)) |
| | | }) |
| | | this.file.uploader.on(event, eventHandler(event)); |
| | | }); |
| | | }, |
| | | destroyed() { |
| | | events.forEach((event) => { |
| | | this.file.uploader.off(event, this._handlers[event]) |
| | | }) |
| | | this._handlers = null |
| | | } |
| | | } |
| | | this.file.uploader.off(event, this._handlers[event]); |
| | | }); |
| | | this._handlers = null; |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style> |