type="accessory"

type="feedback"

父组件
<UploadModal
visible={showAccessory}
// key={accessoryId}
fileLength={10}
key={Math.random() * 10}
format="all"
onCancel={() => this._handleCancel('showAccessory')}
onOk={() => this._handleCancel('showAccessory')}
length={50}
title="上传附件"
type="accessory"
data={{ id: accessoryId }}
downloadUrl="/static/template/信用评价_领域管理导入名单.csv"
uploadUrl="/api/v1.0/creditassess/coupleback/attachment/upload"
/>
子组件
import React, { Component } from 'react';
import { Button, Upload, Icon, Modal, message, Select } from 'antd';
import Classnames from 'classnames';
import styles from './uploadModal.scss';
import { uploadFeedBack, uploadAccessory } from 'services/creditEvaluate/feedbackInfo';
const { Option } = Select;
export default class UploadModal extends Component {
state = {
fileUrl: [],
fileList: [],
uploading: false,
fileType: 'feedback'
}
render() {
const { visible, onCancel, title, okText = '确 认', length = 50, format = 'csv', fileLength, fileSize = 50 } = this.props;
const { validForm, customItem, primaryItem, row } = styles;
const { fileList, fileType, uploading } = this.state;
const props = {
name: 'file',
onRemove: this._removeFile,
beforeUpload: this._beforeUpload,
disabled: !!(fileList.length >= fileLength),
fileList
};
return <Modal
title={title}
visible={visible}
onCancel={onCancel}
className={Classnames('custom-modal', validForm)}
width={500}
maskClosable={false}
footer={
<Button
type="primary"
onClick={this._handleUpload}
disabled={uploading || fileList.length === 0}
loading={uploading}
> {uploading ? '正在上传' : okText} </Button>
}
>
<div className={Classnames(customItem, row)}>
{format === 'all' ? null : <div className="btn-item">
<Icon type="file-text" />
<Select value={fileType} placeholder="请选择上传文件类型" onChange={(fileType) => this._changeFileType(fileType)}>
<Option value="feedback">反馈信息</Option>
<Option value="feedback_sub">反馈信息子表</Option>
<Option value="feedback_list">删除、新增企业名单</Option>
</Select>
</div>}
</div>
<div className={Classnames(primaryItem, row)}>
<div className="btn-item">
<Icon type="file-text" />
<Upload {...props}>
<Button type="primary" disabled={!!(fileList.length >= fileLength)}>添加文件</Button>
</Upload>
</div>
</div>
{format === 'all' ? <div>
<p>1. 支持批量上传,多次上传更新,同时上传文件数量不可超过{fileLength}个;</p>
<p>2. 附件上传格式不做要求;</p>
<p>3. 上传文件名称不可超过{length}个字符;</p>
<p>4. 上传单个文件大小不可超过{fileSize}M;</p>
</div> :
<div>
<p>1. 名单导入支持仅{format}格式,{format}字段间以英文逗号隔开;</p>
<p>2. 上传文件名称不可超过{length}个字符;</p>
<p>3. 上传单个文件大小不可超过{fileSize}M;</p>
</div>}
</Modal>;
}
_beforeUpload = (file) => {
const { format = 'csv', length, fileSize = 50 } = this.props;
const map = { csv: 'csv', excel: 'xls', all: '' };
const isCSV = file.name.indexOf(map[format]) > -1;
const islen = file.name.length <= length;
const isLt2M = file.size / 1024 / 1024 <= fileSize;
if (!isCSV) {
message.error(`只能上传${format}格式的文件!`);
}
if (!islen) {
message.error(`上传文件名称不可超过${length}个字符!`);
}
if (!isLt2M) {
message.error(`上传单个文件大小不可超过${fileSize}M!`);
}
if (isCSV && isLt2M && islen) {
this.setState(state => ({
fileList: [...state.fileList, file]
}));
}
// return isCSV && isLt2M && islen;
return false;
}
_removeFile = (file) => {
this.setState((state) => {
const index = state.fileList.indexOf(file);
const newFileList = state.fileList.slice();
newFileList.splice(index, 1);
return {
fileList: newFileList
};
});
}
_changeFileType(fileType) {
this.setState({ fileType });
}
_handleUpload = () => {
const { fileList, fileType } = this.state;
const { format, type, data, onOk } = this.props;
const formData = new FormData();
fileList.forEach((file) => {
formData.append('file', file);
if (type === 'accessory') {
formData.append('filename', file.name);
}
});
if (type === 'accessory') {
formData.append('id', data.id);
} else {
formData.append('fileType', fileType);
}
this.setState({
uploading: true
});
const map = {
feedback: uploadFeedBack,
accessory: uploadAccessory
};
map[type](formData).then(res => {
onOk();
this.setState({
uploading: false
});
}).catch(e => {
this.setState({
uploading: false
});
});
}
}
弹框样式
@import '../../../vars.scss';
.validForm {
:global {
.btn-item {
// width: 50%;
display: inline-block;
.ant-btn {
width: 150px;
vertical-align: top;
}
}
.btn-item+.btn-item {
margin-left: 30px;
}
.ant-modal-body {
padding-left: 50px;
}
.ant-modal-footer {
padding-bottom: 20px;
}
// .ant-btn {
// width: 120px;
// }
}
}
.detailModal {
p {
width: 60%;
margin: 0 auto;
line-height: 2.5;
span {
font-weight: bold;
}
}
:global {
.ant-modal-body {
padding-bottom: 24px;
}
}
}
.primaryItem {
border-bottom: 1px dashed #DDDDDD;
padding-bottom: 30px;
text-align: center;
:global {
.anticon-file-text {
background-color: #1DDB69;
}
.ant-upload-list-text {
overflow: hidden;
max-width: 200px;
}
}
}
.customItem {
text-align: center;
:global {
.anticon-file-text {
background-color: $primary;
}
.ant-select-selection {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
// .ant-select-selection-selected-value {
// display: block;
// float: none;
// text-align: left;
// width: 100px;
// overflow: hidden;
// white-space: nowrap;
// text-overflow: ellipsis;
// }
}
}
.row {
margin-bottom: 30px;
:global {
.anticon-file-text {
color: $white;
font-size: 40px;
padding: 5px;
//float: left;
}
.ant-upload {
vertical-align: top;
}
.ant-btn {
margin-top: 8px;
margin-left: 16px;
}
.ant-select {
margin-left: 16px;
width: 150px;
float: right;
margin-top: 8px;
}
}
}
网友评论