FileManager.jsx:
import React, { Component } from 'react'
import { Row, Col, Modal, Table, Upload, Button, Breadcrumb, Icon, Progress, message } from 'antd'
import http from "libs/http";
import "./table.module.css";
export default class FileManagerTable extends Component {
state = {
path: ['/'],
tableData: [],
loading: false,
percent: 0,
processVisible: false
}
onClickPathFolder = (e, name) => {
e.preventDefault();
const { path } = this.state;
const newPath = path.slice(0, path.indexOf(name) + 1);
this.setState({
path: newPath
}, function () {
this.getData(this.state.path);
})
}
onOpenFolder = name => {
const { path } = this.state;
this.setState({
path: path.concat(name)
}, function () {
this.getData(this.state.path);
})
}
onDownloadFile = record => {
const { path } = this.state;
var iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.style.height = 0;
iframe.src = `/api/file/object/?name=${record.name}&path=${JSON.stringify(path)}&x-token=${localStorage.token}`;
document.body.appendChild(iframe);
setTimeout(function () {
iframe.remove();
}, 5 * 60 * 1000);
}
onDeleteFile = record => {
const { path } = this.state;
const _this = this;
Modal.confirm({
title: `确定删除文件${record.name}吗?`,
onOk() {
http
.delete(`/api/file/object/?name=${record.name}&path=${JSON.stringify(path)}`)
.then(res => {
message.success(`删除${record.name}成功`);
_this.getData(path);
})
.catch(error => {
console.log(error);
});
},
onCancel() {
message.error(`删除文件${record.name}被取消`);
},
});
}
getData = path => {
this.setState({
loading: true
})
http
.post("/api/file/", JSON.stringify({ path }))
.then(res => {
let tableData = [];
let tableData_D = [];
let tableData_Other = [];
res.sort((a, b) => {
if (a.name > b.name) {
return -1;
} else if (a.name < b.name) {
return 1;
} else {
return 0;
}
})
for (let i = 0; i < res.length; i++) {
if (res[i].kind === "d") {
tableData_D.unshift({
id: i,
name: res[i].name,
size: res[i].size,
date: res[i].date,
kind: res[i].kind,
code: res[i].code
})
} else {
tableData_Other.unshift({
id: i,
name: res[i].name,
size: res[i].size,
date: res[i].date,
kind: res[i].kind,
code: res[i].code
})
}
}
tableData = tableData_D.concat(tableData_Other);
this.setState({
tableData,
loading: false
})
})
.catch(error => {
console.log(error);
this.setState({
loading: false
})
});
}
componentDidMount() {
this.getData(this.state.path);
}
render() {
const { path } = this.state;
const _this = this;
const uploadConfig = {
name: 'fileManagerFile',
showUploadList: false,
action: `/api/file/object/?path=${JSON.stringify(path)}&x-token=${localStorage.token}`,
headers: {
authorization: 'authorization-text',
},
onChange(info) {
if (info.file.status !== 'uploading') {
}
if (info.file.status === 'uploading') {
_this.setState({
processVisible: true,
percent: Math.floor(info.file.percent)
})
}
if (info.file.status === 'done') {
message.success(`${info.file.name}上传成功`);
_this.getData(_this.state.path);
_this.setState({
processVisible: false,
percent: 0
})
} else if (info.file.status === 'error') {
message.error(`${info.file.name}${info.file.response}`);
_this.setState({
processVisible: false,
percent: 0
})
}
},
};
return (
<React.Fragment>
<Row style={{ marginBottom: 15 }}>
<Col span={20}>
<Breadcrumb>
{
path.length === 1 ?
path.map((v, i) => (<Breadcrumb.Item key={v} href="" onClick={e => this.onClickPathFolder(e, v)}><Icon type="home" />
</Breadcrumb.Item>)) :
path.map((v, i) => {
if (i === path.length - 1) {
return (<Breadcrumb.Item key={v}><span>{v}</span></Breadcrumb.Item>);
} else if (i === 0) {
return (<Breadcrumb.Item key={v} href="" onClick={e => this.onClickPathFolder(e, v)}><Icon type="home" /></Breadcrumb.Item>);
} else {
return (<Breadcrumb.Item key={v} href="" onClick={e => this.onClickPathFolder(e, v)}><span>{v}</span></Breadcrumb.Item>);
}
})
}
</Breadcrumb>
</Col>
<Col span={4} style={{ textAlign: 'right' }}>
<Upload {...uploadConfig} >
<Button type="primary" size="small" icon="upload">
上传文件
</Button>
</Upload>
</Col>
</Row>
<Row>
<Col span={24}>
{this.state.processVisible ? <Progress percent={this.state.percent} /> : <></>}
</Col>
</Row>
<Table
rowKey="id"
loading={this.state.loading}
dataSource={this.state.tableData}
pagination={false}
className="fileManagerTable"
scroll={{ y: document.documentElement.clientHeight - 190 }}
>
<Table.Column
title="名称"
dataIndex="name"
key="name"
render={(text, record) => (
record.kind === 'd' ? <Button type="link" icon="folder-open" onClick={() => this.onOpenFolder(text)} title={text}>{text.length > 30 ? text.substring(0, 19) + "..." : text}</Button> : text
)}
/>
<Table.Column
title="大小"
dataIndex="size"
key="size"
width={100}
/>
<Table.Column
title="修改时间"
dataIndex="date"
key="date"
width={170}
/>
<Table.Column
title="属性"
dataIndex="code"
key="code"
width={100}
/>
<Table.Column
title="操作"
render={(text, record) => (<>
{record.kind === '-' ? <>
<Button type="link" icon="download" title="下载" onClick={() => this.onDownloadFile(text)}></Button>
<Button type="link" icon="delete" title="删除" onClick={() => this.onDeleteFile(text)} style={{ color: '#FF0000' }}></Button></> : <></>}
</>)}
width={100}
/>
</Table>
</React.Fragment>
)
}
}
package.json:
{
"name": "FileManager",
"version": "0.1.0",
"private": true,
"dependencies": {
"@antv/data-set": "^0.10.2",
"ace-builds": "^1.4.7",
"antd": "^3.25.0",
"axios": "^0.21.1",
"bizcharts": "^4.1.10",
"echarts": "^4.9.0",
"echarts-for-react": "^2.0.16",
"history": "^4.10.1",
"http-proxy-middleware": "^0.20.0",
"lodash": "^4.17.19",
"mobx": "^5.15.0",
"mobx-react": "^6.1.4",
"moment": "^2.24.0",
"react": "^16.11.0",
"react-ace": "^8.0.0",
"react-dnd": "^14.0.2",
"react-dnd-html5-backend": "^14.0.0",
"react-dom": "^16.11.0",
"react-infinite-scroller": "^1.2.4",
"react-router-dom": "^5.1.2",
"react-scripts": "3.2.0",
"wangeditor": "^4.6.15",
"xterm": "^4.6.0",
"xterm-addon-fit": "^0.4.0"
},
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"buildnomap": "set GENERATE_SOURCEMAP=false&& yarn build",
"test": "react-app-rewired test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@babel/plugin-proposal-decorators": "^7.7.0",
"babel-plugin-import": "^1.12.2",
"customize-cra": "^0.8.0",
"react-app-rewired": "^2.1.5"
}
}