@fe-components/cpv-file
Version:
🔨 A Component for upload file.
542 lines (472 loc) • 15.1 kB
JavaScript
(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 });
})));