zarm-web
Version:
基于 React 的桌面端UI库
217 lines (188 loc) • 5.53 kB
JavaScript
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import React, { Component, cloneElement } from 'react';
import classnames from 'classnames';
class Upload extends Component {
constructor(props) {
super(props);
this.upload = void 0;
this.state = {
fileNumber: 0,
uploading: false
};
}
componentWillReceiveProps(nextProps) {
const {
startUpload
} = this.state;
if ('startUpload' in nextProps) {
this.setState({
startUpload: !!nextProps.startUpload
}, () => {
if (startUpload) {
this.onUploadClick();
}
});
}
} // 选择附件
onSelect() {
const {
files
} = this.upload;
const {
autoUpload,
onSelect
} = this.props;
if (files.length === 0 || onSelect(files) === false) {
return;
} // 自动上传处理
if (autoUpload) {
this.onUploadClick();
}
} // 点击上传按钮
onUploadClick() {
const {
files
} = this.upload;
const {
uploading
} = this.state;
if (files.length === 0 || uploading) {
return;
}
this.setState({
uploading: true,
fileNumber: files.length
});
for (let i = 0; i < files.length; i++) {
this.onUpload(files[i]);
}
} // 上传附件
onUpload(file) {
const {
url,
fileName,
data,
onComplete,
onError
} = this.props;
const URL = /^(http:\/\/|https:\/\/|\/\/)/;
const {
origin
} = window.location;
const fd = new FormData();
const xhr = new XMLHttpRequest();
fd.append(fileName, file);
Object.keys(data).forEach(key => {
fd.append(key, data[key]);
}); // eslint-disable-next-line
// tslint:disable-next-line:no-bitwise
if (URL.test(url) && !~url.indexOf(origin)) {
return onComplete(file);
}
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
onComplete(file, JSON.parse(xhr.responseText));
let {
fileNumber
} = this.state;
const uploading = false;
fileNumber -= 1;
if (fileNumber === 0) {
this.setState({
fileNumber,
uploading
});
this.upload.value = '';
} else {
this.setState({
fileNumber
});
}
} else {
this.setState({
uploading: false
});
this.upload.value = '';
onError();
}
}
}; // 侦查当前附件上传情况
// xhr.upload.onprogress = e => {
// loaded = e.loaded;
// total = e.total;
// percent = Math.floor(100 * loaded / total); //已经上传的百分比
// onProgress(percent);
// };
xhr.open('post', url);
xhr.send(fd);
return true;
}
render() {
const {
multiple,
fileExt,
className,
style,
prefixCls,
children
} = this.props;
const {
uploading
} = this.state;
const cls = classnames({
[prefixCls]: true,
[className]: !!className
});
const childrenNode = React.Children.map(children, (element, index) => {
let extendProps = {};
if (typeof element.type !== 'string') {
// 不是原生dom
extendProps = {
isLoading: 'loading' in element.props || element.props.isLoading || uploading,
isDisabled: 'disabled' in element.props || element.props.isDisabled || uploading
};
}
if (index > 0) {
return cloneElement(element, _objectSpread({}, extendProps));
}
return cloneElement(element, _objectSpread({}, extendProps, {
onClick: () => {
this.upload.click();
}
}));
});
return React.createElement("div", {
className: cls,
style: style
}, React.createElement("input", {
type: "file",
style: {
display: 'none'
},
multiple: multiple,
accept: fileExt,
ref: upload => {
this.upload = upload;
},
onChange: () => this.onSelect()
}), childrenNode);
}
}
Upload.defaultProps = {
prefixCls: 'ui-upload',
fileName: 'files',
startUpload: false,
autoUpload: true,
isRadius: false,
data: {},
url: '',
onSelect: () => {},
onProgress: () => {},
onComplete: () => {},
onError: () => {}
};
Upload.List = void 0;
export default Upload;