app-base-web
Version:
web development common base package.
406 lines (391 loc) • 11.6 kB
JavaScript
import React, { useContext, useState, useRef, useEffect } from 'react'
import { Row, Col, Button, Table, Modal, Form, Upload, Input, Tooltip, Popconfirm, message } from 'antd'
import UtilDate from '../util-date'
import UtilAxios from '../util-axios'
import './style'
const EditableContext = React.createContext();
export default class UploadFile extends React.Component {
constructor(props) {
super(props);
this.state = {
data: this.props.data || [],
pagination: '',
visible: false,
loading: false,
uploadInfo: [],
type: this.props.type || 'left'
}
this.columns = [{
title: "序号",
dataIndex: "id",
width: 100,
render: (text, record, index) => { return index + 1 }
},
{
title: "文件名",
dataIndex: "fileName",
onCell: () => {
return {
style: {
maxWidth: 200,
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
cursor: 'pointer'
}
}
},
render: (text, record) => <Tooltip placement="top" title={text}>
<a href={record.response && record.response.data || ''} target="_blank">{text}</a>
</Tooltip>
},
{
title: "描述",
dataIndex: "fileDesc",
editable: true,
onCell: () => {
return {
style: {
maxWidth: 200,
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
cursor: 'pointer'
}
}
},
render: (text, record) => <Tooltip placement="top" title={text}>{text}</Tooltip>
},
{
title: "大小(kb)",
dataIndex: "fileSize",
width: 100,
render: (text, record) => <span>{(text / 1024).toFixed(2)}</span>
},
{
title: "上传时间",
dataIndex: "uploadTime",
width: 100,
render: (text, record) => <span>{UtilDate.format(text)}</span>
},
{
title: "上传人",
dataIndex: "uploadedBy",
width: 100,
render: (text, record) => <span>{UtilAxios.getUser().name}</span>
},
{
title: "操作",
width: 100,
align: "center",
fixed: "right",
render: (text, record) => {
return <ul>
<li><a onClick={() => console.log("update", record)}><i className="iconfont icon-reload"></i></a></li>
<li>
<Popconfirm placement="topRight" title="确认删除该文件吗?" onConfirm={() => this.onDel(record)}>
<a><i className="iconfont icon-del"></i></a>
</Popconfirm>
</li>
</ul>
}
}]
this.formRef = React.createRef();
}
UNSAFE_componentWillReceiveProps(nextProps) {
// console.log(JSON.parse(nextProps.value));
nextProps.value !== this.props.data && this.setState({
data: JSON.parse(nextProps.value)
})
}
onDel = (record) => {
this.state.data.map((item,index) => {
if(record.uid === item.uid) {
this.state.data.splice(index, 1);
}
})
this.setState({
data: [...this.state.data]
}, this.onChange)
}
onChange = () => {
this.props.onChange && this.props.onChange(JSON.stringify(this.state.data))
}
download = (name, href) => {
let a = document.createElement("a"); //创建a标签
a.setAttribute("target", "_bank");
a.setAttribute("href", href);
a.setAttribute("download", name)
a.click();
console.log(a)
a = null;
}
onDownload = () => {
if(this.state.data.length < 1) {
message.info("没有附件下载!");
return;
}
for (let i = 0; i < this.state.data.length; i++) {
if(this.state.data[i].response && this.state.data[i].response.data) {
this.download(this.state.data[i].fileName, this.state.data[i].response.data);
} else {
message.error(this.state.data[i].fileName +'无下载地址,下载失败')
}
}
}
onSubmit = (value) => {
const { files } = value
if(!files || files.fileList.length === 0) {
message.info("文件为空,无法提交!");
return;
}
const { fileList } = files
let tempList = [];
if(fileList && fileList.length) {
fileList.map((item,index) => {
tempList.push({
"uid": item.uid,
"fileName": item.name,
"fileDesc": value['memo'+ index],
"fileSize": item.size,
"uploadTime": item.lastModifiedDate,
"path": item.response.data,
"businessType": this.props.businessType || '',
"type": this.props.type || '',
"subType": this.props.subType || ''
})
})
this.formRef.current.resetFields();
}
this.setState({
visible: false,
uploadInfo: [],
data: [...this.state.data, ...tempList]
}, this.onChange)
}
render() {
const components = {
body: {
row: EditableRow,
cell: EditableCell,
},
};
const columns = this.columns.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record) => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave: (obj) => {
this.state.data.map((item, index) => {
if(obj.uid === item.uid) {
item.memo = obj.memo
}
})
this.setState({
data: this.state.data
}, this.onChange)
}
}),
};
});
var tableCfg = {
scroll: { y: this.props.height || 300 },
size: "middle",
rowKey: "uid",
columns: columns,
components: components,
rowClassName: () => 'editable-row',
onRow: (record) => {
return {
onClick: event => {
this.setState({ selectedRowId: record.uid })
}
}
},
dataSource: this.state.data,
pagination: false,
loading: this.state.loading,
onChange: (pagination) => {
console.log("table----onchange")
}
}
const uploadCfg = {
name: 'file',
multiple: true,
listType: 'picture',
action: 'https://fastdfs.7ipr.com/ipr/fastdfs/upload',
headers: {
authorization: 'authorization-text',
},
onRemove: file => {
console.log(file)
this.state.uploadInfo.map((item, index) => {
if(item.uid === file.uid) {
this.state.uploadInfo.splice(index, 1);
}
})
this.setState({
uploadInfo: this.state.uploadInfo
})
},
onChange: info => {
if (info.file.status !== 'uploading') {}
if (info.file.status === 'done') {
info.fileList.map(item => {
item.memo = '';
})
this.setState({
uploadInfo: [...info.fileList]
})
message.success(`${info.file.name} 上传成功`);
} else if (info.file.status === 'error') {
message.error(`${info.file.name} 上传失败`);
}
},
};
return (
<div className="uploadfile">
<Modal
title="上传文件"
centered={true}
bodyStyle={{maxHeight: '400px', overflow: 'auto'}}
visible={this.state.visible}
onCancel={() => this.setState({ visible: false })}
footer={[
<Button key="back" className="btn-cancel" onClick={() => { this.setState({ visible: false }) }}>
<i className="iconfont icon-cancel" />取消
</Button>,
<Button key="submit" className="btn-submit" onClick={() => this.formRef.current.submit()}>
<i className="iconfont icon-submit" />提交
</Button>
]}
>
<Form ref={this.formRef} layout="vertical" onFinish={this.onSubmit}>
<Form.Item
name="files"
label="上传文件"
initialValue={this.state.files}
>
<Upload.Dragger {...uploadCfg}>
<i className="iconfont icon-upload" style={{ fontSize: '40px' }} />
</Upload.Dragger>
</Form.Item>
{this.state.uploadInfo.length > 0 && this.state.uploadInfo.map((item,index) => {
return (<Form.Item
key={item.uid}
name={"memo" + index}
label={'文件 "' + item.name + '" 描述'}
initialValue={item.memo}
rules={[{ required: true, message: '请填写描述!' }]}
>
<Input />
</Form.Item>)
})}
</Form>
</Modal>
<div style={{ marginBottom: '14px' }}>
{
this.state.type === 'between' &&
<Row justify="space-between">
<Col xs={6} style={{ color: '#666666' }}>{ this.props.title || 相关附件}</Col>
<Col>
<Button className="btn-upload" onClick={() => this.setState({ visible: true })}><i className="iconfont icon-upload"></i>上传新附件</Button>
</Col>
</Row>
}
{
this.state.type === 'left' &&
<Row justify="space-between">
<Col xs={24}><hr style={{ marginBottom: '10px', background: '#DDDDDD' }} /></Col>
{/* <Col xs={6} style={{ color: '#666666' }}>{ this.props.title || 相关附件}</Col> */}
<Col>
<Button className="btn-upload" style={{marginRight: '10px'}} onClick={() => this.setState({ visible: true })}><i className="iconfont icon-upload"></i>添加附件</Button>
<Button className="btn-export" onClick={this.onDownload}><i className="iconfont icon-export"></i>批量下载</Button>
</Col>
</Row>
}
</div>
<Table {...tableCfg} />
</div>
)
}
}
const EditableRow = ({ index, ...props }) => {
const [form] = Form.useForm();
return (
<Form form={form} component={false}>
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
</Form>
);
};
const EditableCell = ({
title,
editable,
children,
dataIndex,
record,
handleSave,
...restProps
}) => {
const [editing, setEditing] = useState(false);
const inputRef = useRef();
const form = useContext(EditableContext);
useEffect(() => {
if (editing) {
inputRef.current.focus();
}
}, [editing]);
const toggleEdit = () => {
setEditing(!editing);
form.setFieldsValue({
[dataIndex]: record[dataIndex],
});
};
const save = async (e) => {
try {
const values = await form.validateFields();
toggleEdit();
handleSave({ ...record, ...values });
} catch (errInfo) {
console.log('Save failed:', errInfo);
}
};
let childNode = children;
if (editable) {
childNode = editing ? (
<Form.Item
style={{
margin: 0,
}}
name={dataIndex}
rules={[
{
required: true,
message: `${title}不可为空.`,
},
]}
>
<Input ref={inputRef} onPressEnter={save} onBlur={save} />
</Form.Item>
) : (
<div
className="editable-cell-value-wrap"
style={{
paddingRight: 24,
}}
onClick={toggleEdit}
>
{children}
</div>
);
}
return <td {...restProps}>{childNode}</td>;
};