UNPKG

app-base-web

Version:
406 lines (391 loc) 11.6 kB
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>; };