import React from 'react'; import { Button, Icon, message, Upload } from 'antd'; import moment from 'moment'; import Detail from './detail'; import { checkoutFileType } from './utils/utils'; import { getToken } from '../../../../services/globalSearchApi'; import Preview from './preview'; import { getRandom } from '../../../../utils/utils'; import './styles.less'; import { CDN_HOST } from './config'; message.config({ maxCount: 1, }); const formatFileList = ({ list = [], fileList, domain, setFormat }: any) => { return list.map((item, key) => { //增加自定义回显数据格式 let value = setFormat ? setFormat(item) : item; //处理上传成功但没保存到后台的数据(onSaveFileList把数据同步到父组件导致子组件重新渲染处理数据不一致) let file = fileList .filter((f) => f.status === 'done') .find((f) => { const url = `${domain ? 'https://' + domain : CDN_HOST}/${f.response.key}`; return url === value.value; }); if (file) { return file; } //处理保存到后台的数据 return { ...value, uid: value.value, url: value.value, ...checkoutFileType(value.value), }; }); }; const UploadCom: any = class UploadCom extends React.Component { model: any; static getDerivedStateFromProps(nextProps, prevState) { const { prevProps } = prevState; let nextState = { ...prevState, prevProps: nextProps, }; if (JSON.stringify(prevProps.value) !== JSON.stringify(nextProps.value)) { nextState.fileList = formatFileList({ list: nextProps.value, fileList: prevState.fileList, domain: prevState.domain, setFormat: nextProps.setFormat, }); } return nextState; } constructor(props) { super(props); const { value, setFormat } = props; const fileList = formatFileList({ list: value, fileList: [], domain: null, setFormat: setFormat }); this.state = { prevProps: props, fileList, token: null, domain: null, }; } //获取七牛上传token getToken = async () => { let response = await getToken(); if (response && response.success && response.data) { this.setState({ token: response.data.token, domain: response.data.domain, }); } }; //自定义七牛文件唯一key getKey = (file: any) => { if (!file) return; let suffix = file.name.match(/\.\w+$/)[0]; let rand6: string = getRandom(); let time = moment().format('YYYYMMDDHHmmss'); return time + rand6 + suffix; }; //七牛上传额外数据,token和key getData = (file: any) => { const { token } = this.state; return { token, key: this.getKey(file), }; }; static checkoutFileType = checkoutFileType; onSaveFileList = (fileList = []) => { if (this.props.onChange) { const newList = fileList .filter((item: any) => item.value) .map((item: any) => ({ name: item.name, value: item.value, size: item.size, })); this.props.onChange(newList); } }; beforeUpload = async () => { await this.getToken(); return true; }; onChange = ({ file, fileList, event }: any) => { const { domain } = this.state; let newList = fileList; // const filterFilter = fileList.filter((item) => item.status && item.status !== 'done'); // if (filterFilter.length > 5) { // message.warn('文件不能超过5个'); // return; // } if (file.status === 'done' && file.response) { const data = file.response || {}; const url = `${domain ? 'https://' + domain : CDN_HOST}/${data.key}`; //上传成功后处理为服务端数据结构 const itemObj = { uid: file.uid, name: file.name, value: url, size: file.size, url, domain, }; newList = fileList.map((item: any) => { return item.uid === file.uid ? { ...item, ...itemObj } : item; }); this.onSaveFileList(newList); } //ant upload组件实时更新上传状态必须实时setState最新文件列表 this.setState({ fileList: newList }); }; previewFile = (file: any) => { return new Promise((res, rej) => { const obj = checkoutFileType(file.name); const typeArr = file.name.match(/\.[a-zA-Z]+$/); const type = typeArr && typeArr[0] ? typeArr[0].replace('.', '') : ''; if (!['png', 'gif', 'bmp', 'jpg', 'jpeg'].includes(type)) { res(obj.thumbUrl); } }); }; onPreview = (file: any) => { if (this.model && this.model.onPreview) { this.model.onPreview(file.url, file.value); } }; onRemove = (file: any) => { const fileList = this.state.fileList || []; const newFileList = fileList.filter((item) => item.uid !== file.uid); this.onSaveFileList(newFileList); this.setState({ fileList: newFileList }); }; render() { const { btnText, renderButton, listType } = this.props; const { fileList } = this.state; const classObj = { picture: 'upload-list-picture', text: 'upload-list-text', }; return (