简介
具有批量下载图片、打包压缩的能力,并且可以根据需要生成二维码
文件目录
代码
Batch.tsx
import { Button, type ButtonProps } from '@ali/ic-base-antd';
import { useMemoizedFn } from 'ahooks';
import axios from 'axios';
import { saveAs } from 'file-saver';
import JSZip from 'jszip';
import { useState, type FC } from 'react';
import { handleStrToQRLink } from './utils';
export type IBatchDownloadData = Array<{ url: string; name: string }>;
interface IBatchDownloadPictures extends ButtonProps {
data: IBatchDownloadData;
needToQRLink?: boolean;
btnText?: string;
saveName?: string;
handleError?: (msg: string) => void;
onSuccess?: () => void;
}
const BatchDownloadPictures: FC<IBatchDownloadPictures> = ({
data,
needToQRLink = false,
saveName = '文件.zip',
btnText = '批量下载',
handleError,
onSuccess,
...buttonProps
}) => {
const [loading, setLoading] = useState(false);
const getFileData = useMemoizedFn((fileUrl: string) => {
return axios<Blob>(fileUrl, { method: 'get', responseType: 'blob' })
.then((res) => {
console.log('getFileData', res);
return res.data;
})
.catch((e) => {
console.log('err', e);
});
});
const handleBatchDownLoad = useMemoizedFn(() => {
if (!data?.length) {
throw new Error('数据为空');
}
setLoading(true);
const zip = new JSZip();
const promises: Promise<void | Blob>[] = [];
data.forEach((file) => {
const url = needToQRLink ? handleStrToQRLink(file.url) : file.url;
const promise = getFileData(url).then((res) => {
if (res instanceof Blob) {
// 转东八区
const now = new Date();
const localDateTime = new Date(
now.getTime() - now.getTimezoneOffset() * 60000,
);
zip.file(`${file.name}.png`, res, {
binary: true,
date: localDateTime,
});
}
});
promises.push(promise);
});
Promise.all(promises)
.then(() => {
zip
.generateAsync({
type: 'blob',
compression: 'DEFLATE',
compressionOptions: {
level: 9,
},
})
.then((res) => {
saveAs(res, saveName);
onSuccess?.();
})
.catch((e: Error) => {
const msg = e.message ?? '下载失败';
handleError?.(msg);
throw new Error(msg);
});
})
.catch((e: Error) => {
const msg = e.message ?? '网络错误';
handleError?.(msg);
throw new Error(msg);
})
.finally(() => {
setLoading(false);
});
});
return (
<Button {...buttonProps} onClick={handleBatchDownLoad} loading={loading}>
{btnText}
</Button>
);
};
export default BatchDownloadPictures;
utils.ts
import QrCode from 'qrcode-generator';
export const handleStrToQRLink = (data: string) => {
const qr = QrCode(0, 'M');
qr.addData(data);
qr.make();
return qr.createDataURL(10);
};