用React实现一个文件管理器

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"
  }
}

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值