UNPKG

react-webuploader

Version:

a react component for upload files based on webuploader

304 lines (261 loc) 10.1 kB
'use strict'; 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 };