fix:修改批量下载
This commit is contained in:
parent
79e846fae6
commit
222835c762
@ -39,6 +39,7 @@
|
||||
"@codemirror/lang-vue": "^0.1.3",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@fingerprintjs/fingerprintjs": "^4.6.2",
|
||||
"@types/file-saver": "^2.0.7",
|
||||
"@visactor/vchart": "^1.11.0",
|
||||
"@visactor/vchart-arco-theme": "^1.11.0",
|
||||
"@vueuse/core": "^12.4.0",
|
||||
@ -47,8 +48,10 @@
|
||||
"axios": "^1.6.8",
|
||||
"codemirror": "^6.0.1",
|
||||
"driver.js": "^1.3.1",
|
||||
"file-saver": "^2.0.5",
|
||||
"fingerprintjs2": "^2.1.4",
|
||||
"jsbarcode": "^3.11.6",
|
||||
"jszip": "^3.10.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.3.0",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
|
||||
1
src/components.d.ts
vendored
1
src/components.d.ts
vendored
@ -7,7 +7,6 @@ export {}
|
||||
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
copy: typeof import('./components/s-layout-search/index copy.vue')['default']
|
||||
'Index copy': typeof import('./components/s-layout-search/index copy.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
import { ref, Ref } from "vue";
|
||||
import JSZip from "jszip";
|
||||
import { saveAs } from "file-saver";
|
||||
|
||||
type DownloadStatus = "idle" | "loading" | "success" | "error";
|
||||
|
||||
@ -56,35 +58,48 @@ export function useImageDownloader(): any {
|
||||
};
|
||||
|
||||
// 批量下载(并行)
|
||||
const downloadImages = async (urls: string[], customFileNames?: string[]): Promise<DownloadResult[]> => {
|
||||
downloadStatus.value = "loading";
|
||||
batchResults.value = [];
|
||||
const downloadImages = async (urls: string[], customFileNames?: string[]): Promise<void> => {
|
||||
// 可选:更新状态(如果你用 Vue 的 ref)
|
||||
// downloadStatus.value = "loading";
|
||||
|
||||
const promises = urls.map(async (url, index) => {
|
||||
const zip = new JSZip();
|
||||
const errors: string[] = [];
|
||||
|
||||
// 并发获取所有图片(可加并发控制,但 30 个一般没问题)
|
||||
await Promise.all(
|
||||
urls.map(async (url, index) => {
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||
const blob = await response.blob();
|
||||
const link = document.createElement("a");
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = customFileNames?.[index] || extractFileName(url);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(link.href);
|
||||
return { url, status: "success" } as DownloadResult;
|
||||
} catch (error) {
|
||||
console.error(`Failed to download ${url}:`, error);
|
||||
return { url, status: "error", message: (error as Error).message } as DownloadResult;
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||
const blob = await res.blob();
|
||||
let fileName = customFileNames?.[index] || extractFileName(url);
|
||||
// 防止文件名重复(简单处理)
|
||||
if (zip.file(fileName)) {
|
||||
const ext = fileName.includes(".") ? fileName.split(".").pop() : "";
|
||||
const name = fileName.replace(new RegExp(`\\.${ext}$`), "");
|
||||
fileName = `${name}_${Date.now()}.${ext || "jpg"}`;
|
||||
}
|
||||
});
|
||||
zip.file(fileName, blob);
|
||||
} catch (err) {
|
||||
console.error("Download failed:", url, err);
|
||||
errors.push(url);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
const results = await Promise.all(promises);
|
||||
batchResults.value = results;
|
||||
downloadStatus.value = "success";
|
||||
return results;
|
||||
// 生成 ZIP Blob
|
||||
const zipBlob = await zip.generateAsync({ type: "blob" });
|
||||
|
||||
// 触发下载 —— 这是安全的、用户可见的一次性下载
|
||||
saveAs(zipBlob, "车辆二维码.zip");
|
||||
|
||||
// 可选:提示错误
|
||||
if (errors.length > 0) {
|
||||
alert(`成功打包 ${urls.length - errors.length} 张图片。\n失败:${errors.length} 张`);
|
||||
}
|
||||
|
||||
// downloadStatus.value = "success";
|
||||
};
|
||||
|
||||
return {
|
||||
downloadStatus,
|
||||
batchResults,
|
||||
|
||||
@ -132,7 +132,8 @@ const handleDownloadImage = async (record: any) => {
|
||||
// 批量下载
|
||||
const batchDownload = async () => {
|
||||
const urls = select_list.value.map(item => item.bikeQr);
|
||||
const names = select_list.value.map(item => `电池二维码-${item.bikeQrCode}.png`);
|
||||
const names = select_list.value.map(item => `车辆二维码-${item.bikeQrCode}.png`);
|
||||
console.log(urls, names);
|
||||
|
||||
await downloadImages(urls, names);
|
||||
};
|
||||
|
||||
@ -173,9 +173,12 @@ const handleOk = async () => {
|
||||
// 复制图片链接到剪贴板
|
||||
async function copyFileUrl(record: any) {
|
||||
const { fileUrl } = record;
|
||||
console.log(navigator.clipboard);
|
||||
if (navigator.clipboard) {
|
||||
const res: any = await navigator.clipboard.writeText(fileUrl);
|
||||
arcoMessage("success", "复制成功");
|
||||
}
|
||||
}
|
||||
|
||||
async function getImageList() {
|
||||
loading.value = true;
|
||||
|
||||
@ -124,9 +124,9 @@ const handleUpdate = (record: any) => {
|
||||
};
|
||||
|
||||
const handleDelete = async (record: any) => {
|
||||
const { regionId } = record;
|
||||
const { siteId } = record;
|
||||
try {
|
||||
const res: any = await deleteSiteAPI(regionId);
|
||||
const res: any = await deleteSiteAPI(siteId);
|
||||
if (res.code === 200) {
|
||||
arcoMessage("success", "删除成功");
|
||||
getRegionPage();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user