UNPKG

@fe-components/cpv-file

Version:

🔨 A Component for upload file.

542 lines (472 loc) 15.1 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('axios')) : typeof define === 'function' && define.amd ? define(['exports', 'axios'], factory) : (global = global || self, factory(global.CpvFile = {}, global.axios)); }(this, (function (exports, axios) { 'use strict'; axios = axios && Object.prototype.hasOwnProperty.call(axios, 'default') ? axios['default'] : axios; function _broadcast(componentName, eventName, params) { this.$children.forEach(function (child) { var name = child.$options.name; if (name === componentName) { child.$emit.apply(child, [eventName].concat(params)); } else { // todo 如果 params 是空数组,接收到的会是 undefined _broadcast.apply(child, [componentName, eventName].concat([params])); } }); } var Emitter = { methods: { dispatch: function dispatch(componentName, eventName, params) { var parent = this.$parent || this.$root; var name = parent.$options.name; while (parent && (!name || name !== componentName)) { parent = parent.$parent; if (parent) { name = parent.$options.name; } } if (parent) { parent.$emit.apply(parent, [eventName].concat(params)); } }, broadcast: function broadcast(componentName, eventName, params) { _broadcast.call(this, componentName, eventName, params); } } }; var mixinsForm = { // inject: ['formData', 'modalType'], inject: { formData: { type: Object }, modalType: { type: String } }, computed: { isOnlyRead: function isOnlyRead() { return this.modalType === 'readonly'; } } }; // var script = { name: 'CpvFile', mixins: [Emitter, mixinsForm], props: { /** 名称 */ name: { type: String }, /** 属性 */ prop: { type: String }, /** 是否必填 */ required: { type: Boolean }, /** 最大文件大小 以M为单位 */ maxSize: { type: [Number, String] }, /** 是否多选 */ multiple: { type: Boolean }, /** 文件个数 */ fileNum: { type: [Number, String] }, /** token */ token: { type: String }, /** 统一转发地址 */ baseUrl: { type: String } }, data: function data() { return { waitUpload: [], loading: false }; }, computed: { //上传请求的headers headers: function headers() { return this.multiple ? { 'Content-Type': 'multipart/form-data', 'GATEWAY-TOKEN': this.token } : { 'GATEWAY-TOKEN': this.token }; }, //表单校验 ruleValidate: function ruleValidate() { var multiple = this.multiple; if (this.required) { return [{ required: true, type: multiple ? 'array' : 'object', message: '请上传' + this.name, trigger: 'change' }]; } else { return []; } } }, methods: { // 删除待上传文件 delWaitFileList: function delWaitFileList(index) { this.waitUpload.splice(index, 1); }, //删除已上传文件 delFileList: function delFileList(index) { this.formData[this.prop].splice(index, 1); }, //文件上传前钩子 handleBeforeUpload: function handleBeforeUpload(file) { var formData = this.formData; var multiple = this.multiple; var that = this; if (multiple) { var _formData$this$prop; //是否支持多个 var waitUploadLength = that.waitUpload.length || 0; var curLength = ((_formData$this$prop = formData[this.prop]) === null || _formData$this$prop === void 0 ? void 0 : _formData$this$prop.length) || 0; // 限制长度 if (waitUploadLength + curLength >= this.fileNum) { //上传数量限制 this.$Message.info("\u6700\u591A\u53EA\u80FD\u4E0A\u4F20".concat(this.fileNum, "\u4E2A\u6587\u4EF6")); } else { that.waitUpload.push(file); } return false; } else if (!multiple) { this.loading = true; return true; } else { return true; } }, //手动上传 handleUpload: function handleUpload() { var that = this; var formData = this.formData; var prop = this.prop; if (that.waitUpload.length > 0) { that.loading = true; // 创建 formData 对象 var form = new FormData(); // 多个文件上传 for (var i = 0; i < that.waitUpload.length; i++) { form.append('files', that.waitUpload[i]); // 文件对象 } axios.post(that.baseUrl + '/file-api/batchUploadFileByFile', form, { timeout: 10000, headers: this.headers }).then(function (rdata) { if (rdata.data.code === '0') { that.loading = false; that.waitUpload = []; var list = rdata.data.content; var arrays = []; list.forEach(function (elems) { arrays.push({ url: elems.fileUrl, name: elems.fileName }); }); var cur = formData[prop] || []; var total = cur.concat(arrays); if (!formData[prop]) { //判断当前form有无当前属性 而赋值 that.$set(formData, prop, total); } else { formData[prop] = total; } } else { that.loading = false; that.failMsg('服务器错误,请重新上传'); } })["catch"](function (error) { that.loading = false; that.failMsg('服务器错误' + error); }); } else { that.$Message.error('请至少上传一个文件'); } }, //上传成功钩子 uploadSuccess: function uploadSuccess(res, file) { this.loading = false; if (res.code === '0') { file.url = res.content; var prop = this.prop; var formData = this.formData; if (!formData[prop]) { this.$set(this.formData, prop, { url: res.content, name: file.name }); } else { formData[prop] = { url: res.content, name: file.name }; } } else { this.failMsg(res.msg); } }, //上传失败 uploadError: function uploadError(error) { this.failMsg(error); }, //文件大小超出 handleMaxSize: function handleMaxSize() { this.$Notice.warning({ title: '超出文件大小限制', desc: '' + this.maxSize + ' 文件大小超出限制, 请不要超过10M.' }); }, //文件格式校验 upFormatError: function upFormatError(file) { this.$Notice.warning({ title: '超出文件大小限制', desc: '' + file.name + '格式不正确,仅支持压缩(zip/rar)格式的文件' }); }, //下载 linkDownload: function linkDownload(url) { window.open(url, '_blank'); // 新窗口打开外链接 } } }; function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */ , shadowMode, createInjector, createInjectorSSR, createInjectorShadow) { if (typeof shadowMode !== 'boolean') { createInjectorSSR = createInjector; createInjector = shadowMode; shadowMode = false; } // Vue.extend constructor export interop. var options = typeof script === 'function' ? script.options : script; // render functions if (template && template.render) { options.render = template.render; options.staticRenderFns = template.staticRenderFns; options._compiled = true; // functional template if (isFunctionalTemplate) { options.functional = true; } } // scopedId if (scopeId) { options._scopeId = scopeId; } var hook; if (moduleIdentifier) { // server build hook = function hook(context) { // 2.3 injection context = context || // cached call this.$vnode && this.$vnode.ssrContext || // stateful this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext; // functional // 2.2 with runInNewContext: true if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') { context = __VUE_SSR_CONTEXT__; } // inject component styles if (style) { style.call(this, createInjectorSSR(context)); } // register component module identifier for async chunk inference if (context && context._registeredComponents) { context._registeredComponents.add(moduleIdentifier); } }; // used by ssr in case component is cached and beforeCreate // never gets called options._ssrRegister = hook; } else if (style) { hook = shadowMode ? function () { style.call(this, createInjectorShadow(this.$root.$options.shadowRoot)); } : function (context) { style.call(this, createInjector(context)); }; } if (hook) { if (options.functional) { // register for functional component in vue file var originalRender = options.render; options.render = function renderWithStyleInjection(h, context) { hook.call(context); return originalRender(h, context); }; } else { // inject component registration as beforeCreate hook var existing = options.beforeCreate; options.beforeCreate = existing ? [].concat(existing, hook) : [hook]; } } return script; } var normalizeComponent_1 = normalizeComponent; /* script */ var __vue_script__ = script; /* template */ var __vue_render__ = function __vue_render__() { var _vm = this; var _h = _vm.$createElement; var _c = _vm._self._c || _h; return _c("FormItem", _vm._b({ attrs: { label: _vm.name, prop: _vm.prop, rules: _vm.ruleValidate } }, "FormItem", _vm.$attrs, false), [_c("Row", [!_vm.isOnlyRead ? [_c("Col", { attrs: { span: "6" } }, [_c("Upload", { ref: "upload", attrs: { "show-upload-list": false, "on-success": _vm.uploadSuccess, "on-error": _vm.uploadError, headers: _vm.headers, "before-upload": _vm.handleBeforeUpload, "max-size": 1024 * _vm.maxSize, "on-exceeded-size": _vm.handleMaxSize, multiple: _vm.multiple, action: _vm.baseUrl + "/file-api/uploadFile" } }, [_c("Button", { attrs: { icon: "ios-cloud-upload-outline" } }, [_vm._v("上传文件")])], 1)], 1)] : _vm._e(), _vm._v(" "), _vm.waitUpload.length > 0 ? [_c("Col", { attrs: { span: "24" } }, [_vm._l(_vm.waitUpload, function (item, index) { return _c("ul", { key: index, staticClass: "file-list" }, [_c("li", [_vm._v("\n 文件名: "), _c("span", { staticStyle: { "font-size": "14px" } }, [_vm._v(_vm._s(item.name))]), _vm._v(" "), _c("Icon", { staticStyle: { "float": "right" }, attrs: { type: "ios-close", size: "20" }, on: { click: function click($event) { return _vm.delWaitFileList(index); } } })], 1)]); }), _vm._v(" "), _c("Button", { attrs: { loading: _vm.loading, type: "primary" }, on: { click: _vm.handleUpload } }, [_vm._v("上传")])], 2)] : _vm._e(), _vm._v(" "), !_vm.multiple ? [_vm.formData[_vm.prop] ? _c("Col", { attrs: { span: "18" } }, [_c("a", { attrs: { href: _vm.formData[_vm.prop].url, target: "_blank" } }, [_vm._v(_vm._s(_vm.formData[_vm.prop].name))])]) : _vm._e()] : _vm._l(_vm.formData[_vm.prop], function (item, index) { return _c("Col", { key: index, attrs: { span: "24" } }, [_c("a", { attrs: { href: item.url, target: "_blank" } }, [_vm._v(_vm._s(item.name))]), _vm._v(" "), _c("Icon", { staticStyle: { "float": "right" }, attrs: { disabled: _vm.isOnlyRead, type: "ios-close", size: "20" }, on: { click: function click($event) { return _vm.delFileList(index); } } })], 1); })], 2), _vm._v(" "), _vm.loading ? _c("Row", { staticStyle: { position: "relative" } }, [_c("Spin", [_c("Tag", { attrs: { color: "warning" } }, [_vm._v("文件上传中 ! 请耐心等待...")])], 1), _vm._v(" "), _c("div", { staticStyle: { margin: "50px", position: "relative" } }, [_c("Spin", { attrs: { fix: "", size: "large" } })], 1)], 1) : _vm._e()], 1); }; var __vue_staticRenderFns__ = []; __vue_render__._withStripped = true; /* style */ var __vue_inject_styles__ = undefined; /* scoped */ var __vue_scope_id__ = undefined; /* module identifier */ var __vue_module_identifier__ = undefined; /* functional template */ var __vue_is_functional_template__ = false; /* style inject */ /* style inject SSR */ var Component = normalizeComponent_1({ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ }, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, undefined, undefined); // Import vue component // the same plugin more than once, // so calling it multiple times on the same plugin // will install the plugin only once Component.install = function (Vue) { Vue.component(Component.name, Component); }; // To auto-install when vue is found var GlobalVue = null; if (typeof window !== 'undefined') { GlobalVue = window.Vue; } else if (typeof global !== 'undefined') { GlobalVue = global.Vue; } if (GlobalVue) { GlobalVue.use(Component); } // To allow use as module (npm/webpack/etc.) export component // also be used as directives, etc. - eg. import { RollupDemoDirective } from 'rollup-demo'; // export const RollupDemoDirective = component; exports.default = Component; Object.defineProperty(exports, '__esModule', { value: true }); })));