Browse Source

下载组件

main
dark 7 months ago
parent
commit
2e1093624b
  1. 58
      src/components/download/Download.tsx
  2. 0
      src/components/download/index.ts
  3. 13
      src/pages/websites/ssl/index.tsx
  4. 20
      src/request.ts
  5. 6
      src/service/websites.ts

58
src/components/download/Download.tsx

@ -0,0 +1,58 @@
import React, { useEffect, useRef, useState } from 'react'
import { LoadingOutlined } from '@ant-design/icons'
export interface DownloadProps {
children?: React.ReactNode;
className?: string;
style?: React.CSSProperties;
server?: () => Promise<any>
fileName?: string
[key: string]: any
}
const Download = ({ server, style, className, fileName, children, ...props }: DownloadProps) => {
const [ isLoading, setLoading ] = useState(false)
const serverRef = useRef(server)
serverRef.current = server
useEffect(() => {
serverRef.current = server
}, [ server ])
return (
<div className={className}
style={style} {...props}
onClick={() => {
if (isLoading) return
serverRef.current && serverRef.current()?.then(res => {
if (!res) {
return res
}
const downloadUrl = window.URL.createObjectURL(new Blob([ res ]))
const a = document.createElement('a')
a.style.display = 'none'
a.href = downloadUrl
a.download = fileName || ''
const event = new MouseEvent('click')
a.dispatchEvent(event)
window.URL.revokeObjectURL(downloadUrl)
setTimeout(() => a.remove())
return res
})?.finally(() => {
setLoading(false)
})
}}
>
{isLoading && <LoadingOutlined/>}
{children}
</div>
)
}
export default Download

0
src/components/download/index.ts

13
src/pages/websites/ssl/index.tsx

@ -30,6 +30,7 @@ import SSLDetail from './components/Detail.tsx'
import { detailAtom } from './components/store.ts' import { detailAtom } from './components/store.ts'
import Upload from './components/Upload.tsx' import Upload from './components/Upload.tsx'
import { FormInstance } from 'antd/lib' import { FormInstance } from 'antd/lib'
import Download from '@/components/download/Download.tsx'
const SSL = () => { const SSL = () => {
@ -261,14 +262,12 @@ const SSL = () => {
</Else> </Else>
</If>, </If>,
<Action key="download"
as={'a'}
onClick={() => {
<Download key="download"
server={async () => {
}} }}
> >
{t('actions.download', '下载')}
</Action>,
<a>{t('actions.download', '下载')}</a>
</Download>,
<Popconfirm <Popconfirm
key={'del_confirm'} key={'del_confirm'}
disabled={isDeleting} disabled={isDeleting}
@ -343,7 +342,7 @@ const SSL = () => {
</Button>}> </Button>}>
<DNSList/> <DNSList/>
</DrawerPicker>, </DrawerPicker>,
<Button type={'primary'} onClick={()=>{
<Button type={'primary'} onClick={() => {
uploadDrawerRef.current?.open() uploadDrawerRef.current?.open()
}}> }}>
{t('website.ssl.actions.upload', '上传证书')} {t('website.ssl.actions.upload', '上传证书')}

20
src/request.ts

@ -11,7 +11,8 @@ import axios, {
export type { AxiosRequestConfig } export type { AxiosRequestConfig }
type FetchMethod = <T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>) => Promise<IApiResult<T>> type FetchMethod = <T = any, D = any>(url: string, data?: D, config?: AxiosRequestConfig<D>) => Promise<IApiResult<T>>
interface RequestMethods extends Pick<AxiosInstance, 'get' | 'post' | 'put' | 'delete' | 'request' | 'postForm' | 'patch' | 'patchForm' | 'putForm' | 'options'> {
interface RequestMethods extends Pick<AxiosInstance, 'get' | 'post' | 'put' | 'delete' | 'request' | 'postForm' | 'patch' | 'patchForm' | 'putForm' | 'options' > {
download: (url: string, data?: any) => Promise<BlobPart>
} }
@ -119,6 +120,23 @@ axiosInstance.interceptors.response.use(
return Promise.reject(error) return Promise.reject(error)
}) })
//扩展download方法
// @ts-ignore fix download
axiosInstance.download = (url: string, data?: any) => {
const formData = new FormData()
for (const key in data) {
formData.append(key, data[key])
}
const config = {
method: 'post',
url,
data: formData,
responseType: 'blob',
timeout: 40 * 1000,
} as AxiosRequestConfig
return axiosInstance.request(config)
}
//创建返回IApiResult类型的request //创建返回IApiResult类型的request
export const createFetchMethods = () => { export const createFetchMethods = () => {

6
src/service/websites.ts

@ -7,8 +7,10 @@ const websitesServ = {
...createCURD<any, WebSite.ISSL>('/website/ssl'), ...createCURD<any, WebSite.ISSL>('/website/ssl'),
upload: async(params: WebSite.SSLUploadDto)=>{ upload: async(params: WebSite.SSLUploadDto)=>{
return request.post<any, WebSite.SSLUploadDto>('/website/ssl/upload', params) return request.post<any, WebSite.SSLUploadDto>('/website/ssl/upload', params)
}
},
download: async(params: any)=>{
return request.download('/website/ssl/download', params)
},
}, },
acme: { acme: {
...createCURD<any, WebSite.IAcmeAccount>('/website/acme') ...createCURD<any, WebSite.IAcmeAccount>('/website/acme')

Loading…
Cancel
Save