react-webuploader
Version:
a react component for upload files based on webuploader
304 lines (261 loc) • 10.1 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _uuid = require('uuid');
var _uuid2 = _interopRequireDefault(_uuid);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _jquery = require('jquery');
var _jquery2 = _interopRequireDefault(_jquery);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
window.jQuery = _jquery2.default;
var noop = function noop() {};
var webuploader = require('webuploader');
var WebUploader = function (_React$Component) {
_inherits(WebUploader, _React$Component);
function WebUploader(props) {
_classCallCheck(this, WebUploader);
var _this = _possibleConstructorReturn(this, (WebUploader.__proto__ || Object.getPrototypeOf(WebUploader)).call(this, props));
_this.state = {};
_this.key = props.key || (0, _uuid2.default)();
return _this;
}
_createClass(WebUploader, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.initWebUploaderHook();
this.createWebUploaderInterface();
this.bindWebUploaderEvent();
}
}, {
key: 'initWebUploaderHook',
value: function initWebUploaderHook() {
var server = this.props.server;
webuploader.Uploader.register({
'before-send-file': 'beforeSendFile',
'before-send': 'beforeSend',
'after-send-file': 'afterSendFile'
}, {
beforeSendFile: function beforeSendFile(file) {
var _this2 = this;
var dfd = new _jquery2.default.Deferred();
var md5 = file.md5,
size = file.size,
ext = file.ext;
// 通过 md5 监测文件是否上传过
_jquery2.default.get(server + '/upload/filecheck?md5=' + md5 + '&size=' + size + '&ext=' + ext).done(function (_ref) {
var exists = _ref.exists,
path = _ref.path;
if (exists) {
file.path = path;
_this2.uploader.skipFile(file);
dfd.reject();
} else {
dfd.resolve();
}
}).fail(function () {
dfd.resolve();
});
return _jquery2.default.when(dfd);
},
beforeSend: function beforeSend(_ref2) {
var _ref2$file = _ref2.file,
md5 = _ref2$file.md5,
ext = _ref2$file.ext,
size = _ref2$file.size,
chunk = _ref2.chunk;
// 分片验证是否已传过,用于断点续传
var dfd = new _jquery2.default.Deferred();
_jquery2.default.get(server + '/upload/chunkcheck?md5=' + md5 + '&chunk=' + chunk + '&size=' + size + '&ext=' + ext).done(function (_ref3) {
var exists = _ref3.exists;
if (exists) {
dfd.reject();
} else {
dfd.resolve();
}
}).fail(function () {
dfd.resolve();
});
return _jquery2.default.when(dfd);
},
afterSendFile: function afterSendFile(file) {
var md5 = file.md5,
size = file.size,
ext = file.ext;
var chunkSize = this.options.chunkSize;
var chunks = Math.ceil(size / chunkSize) || 0;
if (chunks > 1) {
var dfd = new _jquery2.default.Deferred();
_jquery2.default.ajax({
url: server + '/upload/chunksmerge',
method: 'POST',
data: JSON.stringify({
md5: md5, size: size, ext: ext, chunks: chunks
}),
contentType: 'application/json'
}).done(function (_ref4) {
var path = _ref4.path;
file.path = path;
dfd.resolve();
}).fail(function () {
dfd.reject();
});
return _jquery2.default.when(dfd);
}
}
});
}
}, {
key: 'createWebUploaderInterface',
value: function createWebUploaderInterface() {
var _props = this.props,
server = _props.server,
key = _props.key,
chunked = _props.chunked,
formData = _props.formData,
fileNumLimit = _props.fileNumLimit,
threads = _props.threads,
auto = _props.auto;
this.uploader = webuploader.create({
pick: '#' + key,
server: server + '/upload',
chunked: chunked,
formData: formData,
fileNumLimit: fileNumLimit,
threads: threads,
auto: auto
});
}
}, {
key: 'bindWebUploaderEvent',
value: function bindWebUploaderEvent() {
var _props2 = this.props,
fileQueued = _props2.fileQueued,
uploadStart = _props2.uploadStart,
uploadSuccess = _props2.uploadSuccess,
uploadComplete = _props2.uploadComplete,
uploadProgress = _props2.uploadProgress,
onError = _props2.onError;
this.uploader
// fileQueued 文件加入队列
.on('fileQueued', function (file) {
var _this3 = this;
this.md5File(file, 0, 1 * 1024 * 1024).then(function (ret) {
file.md5 = ret;
_this3.options.formData.md5 = ret;
file.tempKey = (0, _uuid2.default)();
// 刚刚入队的文件进度设置为 0
file.percentage = 0;
// 需要保证文件获取 md5 完成后再回掉, 保证 ui 和逻辑的联动
fileQueued(file);
_this3.upload();
});
})
// 上传开始
.on('uploadStart', function (file) {
uploadStart(file);
})
// 文件上传成功时触发
.on('uploadSuccess', function (file, data) {
uploadSuccess(file, data);
if (data && data.path) {
file.path = data.path;
}
uploadSuccess(file);
})
// 上传完成, 成功 or 失败都会触发
.on('uploadComplete', function (file) {
uploadComplete();
this.removeFile(file.id);
})
// 更新上传进度
.on('uploadProgress', function (file, percentage) {
uploadProgress(file, Math.floor(percentage * 100));
}).on('error', function (error) {
console.log('\u5F53\u524D\u65F6\u95F4 ' + Date.now() + ': debug \u7684\u6570\u636E\u662F error: ', error);
onError(error);
});
}
}, {
key: 'handleChooseFile',
value: function handleChooseFile() {
var uploaderBtn = this.uploaderWrap.querySelector('input');
if (uploaderBtn) {
uploaderBtn.click();
} else {
throw new Error('react-webuploader init failed~\n please reload the page or contact your developer');
}
}
}, {
key: 'render',
value: function render() {
var _this4 = this;
return _react2.default.createElement('div', {
ref: function ref(_ref5) {
_this4.uploaderWrap = _ref5;
},
id: this.key,
key: this.key
});
}
}]);
return WebUploader;
}(_react2.default.Component);
exports.default = WebUploader;
WebUploader.propTypes = {
/**
* base Conf
*/
// 上传组件标识
key: _propTypes2.default.string,
// 是否要分片处理大文件上传
chunked: _propTypes2.default.bool,
// 上传服务域名
server: _propTypes2.default.string.isRequired,
// 文件上传请求的参数表, 每次发送都会发送此对象中的参数
formData: _propTypes2.default.object, // eslint-disable-line
// 验证文件总数量, 超出则不允许加入队列, 默认值 5
fileNumLimit: _propTypes2.default.number,
// 上传并发数, 允许同时最大上传进程数, 默认值 3
threads: _propTypes2.default.number,
// 选择文件后是否自动上传
auto: _propTypes2.default.bool,
/**
* call Backs
*/
// 文件加入队列
fileQueued: _propTypes2.default.func,
// 开始上传
uploadStart: _propTypes2.default.func,
// 上传成功
uploadSuccess: _propTypes2.default.func,
// 上传完成
uploadComplete: _propTypes2.default.func,
// 更新进度
uploadProgress: _propTypes2.default.func,
// 错误处理
onError: _propTypes2.default.func
};
WebUploader.defaultProps = {
key: (0, _uuid2.default)(),
chunked: false,
formData: {
md5: ''
},
fileNumLimit: 5,
threads: 3,
auto: true,
fileQueued: noop,
uploadStart: noop,
uploadSuccess: noop,
uploadComplete: noop,
uploadProgress: noop,
onError: noop
};
;