# 下载文件通用组件DownloadPanel与DownloadButton

组件来源: 办公系统v3 - common组件

## 1.功能说明

插入该组件DownloadPanel，或插入DownloadPanel与DownloadButton，实现通过url下载远程文件到本地或者通过远程minio服务器下载文件到本地。

## 2.组件依赖

### (1)DownloadPanel组件依赖

- react

- antd

- axios

- 通用组件DragModal

### (2)DownloadButton组件依赖

- react

- antd

- 通用组件DownloadPanel

## 3.依赖结构体

```tsx
//下载组件上下文接口
export interface DownloadState {
    files: DownloadFile[]
    visible: boolean
    startDownload: (file: DownloadFile[], onCloseCallbackFn?: () => void) => void  //下载结束后的回调，可用于关闭下载框等用途
    onEnd: () => void
}

export interface DownloadFile {
    //如果要调用api传递文件需要前四个变量不为空  如果直接通过url传递文件则需要后三项不为空
    objectName?: string
    bucketName?: string

    filename: string
    suffix: string
    
    url?: string
}
```

## 4.组件接口

### (1)DownloadPanel组件接口

```tsx
interface Iprops {
    //该api返回一个url
    getFileUrl?: (params?: {}) => Promise<AxiosResponse<any>>
    downloadContext: React.Context<DownloadState>
}

```

### (2)DownloadButton组件接口

```tsx
interface IProps {
    disabled?: boolean
    downloadFileContext: React.Context<DownloadState>
    title: string
    files: DownloadFile[]  //需要下载的文件
    onCloseCallbackFn?: () => void
}
```

## 5.使用方法

### (1)DownloadPanel组件使用方法

1) 在项目最外层插入DownloadPanel组件与对应上下文

下面例子为添加到App.tsx中

```tsx
import React from 'react';
import DownloadPanel, { DownloadState, useDownloadService } from './common/download-panel/download-panel';

export const DownloadContext = React.createContext<DownloadState>(null);

function App() {
    return (
        <DownloadContext.Provider value={useDownloadService()}>
            <DownloadPanel getFileUrl={...} downloadContext={DownloadContext}/>
        </DownloadContext.Provider>
        )
}
export default App;
```

2) 在需要使用下载功能的子组件中，引入App.tsx中定义的DownloadContext，并调用downloadContext.startDownload(files)

```tsx
import { useState } from 'react';
import { DownloadContext } from '../App';
import { DownloadFile } from '../common/download-panel/download-panel';
import { ArrowUpOutlined } from "@ant-design/icons";

export default function X() {
    //引入上下文
    const downloadContext = useContext(DownloadContext);
    //定义下载文件（这里没有使用api，直接赋予文件url）
    const files = [
            {url : "https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/css/pluginsCss.css", suffix: ".css", filename:"pluginsCss"},
            {url : "https://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js", suffix: ".js", filename:"luckysheet.umd"},
            {url : "https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/js/plugin.js", suffix: ".js", filename:"plugin"}
        ]

    return (
        <div className="main-X-container">
            <Button icon={<ArrowDownOutlined />} title={"下载"} size="small" disabled={false} onClick={(e) => {
                e.stopPropagation();
                e.preventDefault();
                downloadContext.startDownload(files)
            }}></Button>
        </div>
    )
}
```

### (2)DownloadButton组件使用方法

第一步与DownloadPanel组件使用方法一致，对于第二步，我们看一个使用了下载后回调函数的例子，这个例子会在下载结束后，将下载按钮下面的div背景颜色改为红色

```tsx
import { useEffect, useState } from 'react';
import { DownloadContext } from '../App';
import DownloadButton from '../common/download-panel/download-button';

export default function X() {
    const files = [
            {url : "https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/css/pluginsCss.css", suffix: ".css", filename:"pluginsCss"},
            {url : "https://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js", suffix: ".js", filename:"luckysheet.umd"},
            {url : "https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/js/plugin.js", suffix: ".js", filename:"plugin"}
        ]
    const [color, setColor] = useState<string>("#ffffff");
    return (
        <div className="main-layout-container">
            <DownloadButton downloadFileContext={DownloadContext} files={files} onCloseCallbackFn={() => {setColor("#ff0000")}}/>
            <div style={{backgroundColor:color}} onClick={()=>{setColor("#ffffff")}}>还原</div>
        </div>
    )
}
```

