forked from p96170835/amis
文件上传优化
This commit is contained in:
parent
f6d329f9ac
commit
cacb6e5626
|
@ -144,4 +144,12 @@
|
||||||
line-height: 120px;
|
line-height: 120px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-sum {
|
||||||
|
font-size: $fontSizeSm;
|
||||||
|
|
||||||
|
> a {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import ImageControl from './Image';
|
||||||
import {Payload, ApiObject, ApiString} from '../../types';
|
import {Payload, ApiObject, ApiString} from '../../types';
|
||||||
import {filter} from '../../utils/tpl';
|
import {filter} from '../../utils/tpl';
|
||||||
import Alert from '../../components/Alert2';
|
import Alert from '../../components/Alert2';
|
||||||
import {qsstringify, createObject} from '../../utils/helper';
|
import {qsstringify, createObject, guid} from '../../utils/helper';
|
||||||
import {buildApi} from '../../utils/api';
|
import {buildApi} from '../../utils/api';
|
||||||
import Button from '../../components/Button';
|
import Button from '../../components/Button';
|
||||||
import {Icon} from '../../components/icons';
|
import {Icon} from '../../components/icons';
|
||||||
|
@ -83,12 +83,6 @@ export interface FileState {
|
||||||
files: Array<FileX | FileValue>;
|
files: Array<FileX | FileValue>;
|
||||||
error?: string | null;
|
error?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let id = 1;
|
|
||||||
function gennerateId() {
|
|
||||||
return id++;
|
|
||||||
}
|
|
||||||
|
|
||||||
let preventEvent = (e: any) => e.stopPropagation();
|
let preventEvent = (e: any) => e.stopPropagation();
|
||||||
|
|
||||||
export function getNameFromUrl(url: string) {
|
export function getNameFromUrl(url: string) {
|
||||||
|
@ -134,6 +128,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||||
state: FileState;
|
state: FileState;
|
||||||
current: FileValue | FileX | null;
|
current: FileValue | FileX | null;
|
||||||
resolve?: (value?: any) => void;
|
resolve?: (value?: any) => void;
|
||||||
|
emitValue: any;
|
||||||
|
|
||||||
static valueToFile(
|
static valueToFile(
|
||||||
value: string | FileValue,
|
value: string | FileValue,
|
||||||
|
@ -151,17 +146,19 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||||
value: value,
|
value: value,
|
||||||
name: value.name,
|
name: value.name,
|
||||||
url: '',
|
url: '',
|
||||||
id: gennerateId()
|
id: guid()
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
...(typeof value === 'string'
|
...(typeof value === 'string'
|
||||||
? {
|
? {
|
||||||
state: file && file.state ? file.state : 'init',
|
state: file && file.state ? file.state : 'init',
|
||||||
value,
|
value,
|
||||||
name: /^data:/.test(value)
|
name:
|
||||||
? (file && file.name) || 'base64数据'
|
(file && file.name) ||
|
||||||
: getNameFromUrl(value),
|
(/^data:/.test(value)
|
||||||
id: gennerateId(),
|
? 'base64数据'
|
||||||
|
: getNameFromUrl(value)),
|
||||||
|
id: guid(),
|
||||||
url:
|
url:
|
||||||
typeof props.downloadUrl === 'string' &&
|
typeof props.downloadUrl === 'string' &&
|
||||||
value &&
|
value &&
|
||||||
|
@ -209,6 +206,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||||
this.handleDropRejected = this.handleDropRejected.bind(this);
|
this.handleDropRejected = this.handleDropRejected.bind(this);
|
||||||
this.startUpload = this.startUpload.bind(this);
|
this.startUpload = this.startUpload.bind(this);
|
||||||
this.stopUpload = this.stopUpload.bind(this);
|
this.stopUpload = this.stopUpload.bind(this);
|
||||||
|
this.retry = this.retry.bind(this);
|
||||||
this.toggleUpload = this.toggleUpload.bind(this);
|
this.toggleUpload = this.toggleUpload.bind(this);
|
||||||
this.tick = this.tick.bind(this);
|
this.tick = this.tick.bind(this);
|
||||||
this.onChange = this.onChange.bind(this);
|
this.onChange = this.onChange.bind(this);
|
||||||
|
@ -220,7 +218,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||||
componentWillReceiveProps(nextProps: FileProps) {
|
componentWillReceiveProps(nextProps: FileProps) {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
|
|
||||||
if (props.value !== nextProps.value) {
|
if (props.value !== nextProps.value && this.emitValue !== nextProps.value) {
|
||||||
const value: string | Array<string | FileValue> | FileValue =
|
const value: string | Array<string | FileValue> | FileValue =
|
||||||
nextProps.value;
|
nextProps.value;
|
||||||
const multiple = nextProps.multiple;
|
const multiple = nextProps.multiple;
|
||||||
|
@ -295,7 +293,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||||
file.state = 'pending';
|
file.state = 'pending';
|
||||||
}
|
}
|
||||||
|
|
||||||
file.id = gennerateId();
|
file.id = guid();
|
||||||
inputFiles.push(file);
|
inputFiles.push(file);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -327,7 +325,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||||
const files = rejectedFiles.map((file: any) => ({
|
const files = rejectedFiles.map((file: any) => ({
|
||||||
...file,
|
...file,
|
||||||
state: 'invalid',
|
state: 'invalid',
|
||||||
id: gennerateId(),
|
id: guid(),
|
||||||
name: file.name
|
name: file.name
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -350,7 +348,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||||
this.dropzone.current && this.dropzone.current.open();
|
this.dropzone.current && this.dropzone.current.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
startUpload() {
|
startUpload(retry: boolean = false) {
|
||||||
if (this.state.uploading) {
|
if (this.state.uploading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -359,8 +357,9 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||||
{
|
{
|
||||||
uploading: true,
|
uploading: true,
|
||||||
files: this.state.files.map(file => {
|
files: this.state.files.map(file => {
|
||||||
if (file.state === 'error') {
|
if (retry && file.state === 'error') {
|
||||||
file.state = 'pending';
|
file.state = 'pending';
|
||||||
|
file.progress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
|
@ -385,6 +384,10 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retry() {
|
||||||
|
this.startUpload(true);
|
||||||
|
}
|
||||||
|
|
||||||
tick() {
|
tick() {
|
||||||
if (this.current || !this.state.uploading) {
|
if (this.current || !this.state.uploading) {
|
||||||
return;
|
return;
|
||||||
|
@ -617,7 +620,7 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||||
value = typeof resetValue === 'undefined' ? '' : resetValue;
|
value = typeof resetValue === 'undefined' ? '' : resetValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(value);
|
onChange((this.emitValue = value));
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadFile(
|
uploadFile(
|
||||||
|
@ -880,6 +883,18 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||||
|
|
||||||
const hasPending = files.some(file => file.state == 'pending');
|
const hasPending = files.some(file => file.state == 'pending');
|
||||||
|
|
||||||
|
let uploaded = 0;
|
||||||
|
let failed = 0;
|
||||||
|
|
||||||
|
this.state.uploading ||
|
||||||
|
this.state.files.forEach(item => {
|
||||||
|
if (item.state === 'error') {
|
||||||
|
failed++;
|
||||||
|
} else if (item.state === 'uploaded') {
|
||||||
|
uploaded++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx('FileControl', className)}>
|
<div className={cx('FileControl', className)}>
|
||||||
<DropZone
|
<DropZone
|
||||||
|
@ -1006,8 +1021,11 @@ export default class FileControl extends React.Component<FileProps, FileState> {
|
||||||
)}
|
)}
|
||||||
</DropZone>
|
</DropZone>
|
||||||
|
|
||||||
{error ? (
|
{failed ? (
|
||||||
<div className={cx('FileControl-errorMsg')}>{error}</div>
|
<div className={cx('FileControl-sum')}>
|
||||||
|
已成功上传{uploaded}个文件,{failed}个文件上传上传失败,
|
||||||
|
<a onClick={this.retry}>重新上传</a>失败文件
|
||||||
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{!autoUpload && !hideUploadButton && files.length ? (
|
{!autoUpload && !hideUploadButton && files.length ? (
|
||||||
|
|
|
@ -318,6 +318,7 @@ export default class ImageControl extends React.Component<
|
||||||
files: this.files = this.files.map(file => {
|
files: this.files = this.files.map(file => {
|
||||||
if (retry && file.state === 'error') {
|
if (retry && file.state === 'error') {
|
||||||
file.state = 'pending';
|
file.state = 'pending';
|
||||||
|
file.progress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
|
|
Loading…
Reference in New Issue