diff --git a/ebike-operate/src/utils/tools.js b/ebike-operate/src/utils/tools.js index 16468cb..af2821a 100644 --- a/ebike-operate/src/utils/tools.js +++ b/ebike-operate/src/utils/tools.js @@ -77,4 +77,95 @@ export function isNullOrEmpty(value){ return true; else return false; +} + + + +/** + * 批量下载图片(兼容IE10+及现代浏览器) + * @param {Array} imgList - 图片数据数组,支持base64或URL + */ +export function batchDownloadQRcodes(imgList) { + // 检查是否为 IE 浏览器,通过判断是否存在 msSaveBlob 方法 + const isIE = window.navigator.msSaveBlob!== undefined; + + // 下载单张图片的函数 + const downloadSingleImage = (imgObj) => { + const { base64QrCode, code } = imgObj; + // 拼接文件名,使用 bikeCode 作为主要标识 + const fileName = `${code}.png`; + + if (base64QrCode.startsWith('data:')) { + // 处理 Base64 格式的图片数据 + const [mime, data] = base64QrCode.split(';base64,'); + const mimeType = mime.replace('data:', ''); + const byteCharacters = atob(data); + const byteNumbers = new Array(byteCharacters.length); + + for (let i = 0; i < byteCharacters.length; i++) { + byteNumbers[i] = byteCharacters.charCodeAt(i); + } + + const byteArray = new Uint8Array(byteNumbers); + const blob = new Blob([byteArray], { type: mimeType }); + + if (isIE) { + // IE 浏览器专用的下载方法 + window.navigator.msSaveBlob(blob, fileName); + } else { + // 现代浏览器的下载方式,创建 blob URL 并触发下载 + const url = URL.createObjectURL(blob); + triggerDownload(url, fileName); + URL.revokeObjectURL(url); + } + } else { + // 处理图片为普通 URL 格式的情况(跨域可能受限,需服务端配合设置跨域头) + if (isIE) { + // IE 下使用 XMLHttpRequest 下载 + const xhr = new XMLHttpRequest(); + xhr.open('GET', base64QrCode, true); + xhr.responseType = 'blob'; + + xhr.onload = function () { + if (xhr.status === 200) { + window.navigator.msSaveBlob(xhr.response, fileName); + } + }; + + xhr.send(); + } else { + // 现代浏览器使用 fetch 下载 + fetch(base64QrCode) + .then(res => res.blob()) + .then(blob => { + const url = URL.createObjectURL(blob); + triggerDownload(url, fileName); + URL.revokeObjectURL(url); + }) + .catch(err => console.error('下载失败:', err)); + } + } + }; + + // 创建下载链接并触发点击的函数 + const triggerDownload = (url, fileName) => { + const link = document.createElement('a'); + link.href = url; + link.download = fileName; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }; + + // 按顺序下载图片,避免浏览器并发限制 + const downloadNext = (index) => { + if (index >= imgList.length) return; + + downloadSingleImage(imgList[index], index); + + // 间隔 500ms 下载下一个,可根据实际情况调整间隔时间 + setTimeout(() => downloadNext(index + 1), 500); + }; + + downloadNext(0); } \ No newline at end of file diff --git a/ebike-operate/src/views/Layout/index.vue b/ebike-operate/src/views/Layout/index.vue index e171239..228a2f1 100644 --- a/ebike-operate/src/views/Layout/index.vue +++ b/ebike-operate/src/views/Layout/index.vue @@ -107,9 +107,11 @@ - + - +
+ +
@@ -273,4 +275,16 @@ const onOperationClick = (e) => { opacity: 1; } } + +.custom-layout-content{ + height: calc(100vh - 64px); + overflow: hidden; +} + +.custom-layout-content .content-wrapper { + height: 100%; + overflow-y: auto; + padding: 24px; + box-sizing: border-box; +} diff --git a/ebike-operate/src/views/Produce/BatteryQRCode/index.vue b/ebike-operate/src/views/Produce/BatteryQRCode/index.vue index c5c1d00..ebf7ddb 100644 --- a/ebike-operate/src/views/Produce/BatteryQRCode/index.vue +++ b/ebike-operate/src/views/Produce/BatteryQRCode/index.vue @@ -104,6 +104,17 @@ 绑定 + + + + 批量下载 + + +const batchDownload = () => { + if( batchDownloadList.value.length === 0) { + message.error('请选择要下载的二维码') + return + } + + const urls = batchDownloadList.value.map(item => { + return { + base64QrCode:item.base64QrCode, + code:item.batteryCode + } + }); + batchDownloadQRcodes(urls) +} + + \ No newline at end of file diff --git a/ebike-operate/src/views/Produce/BikeQRCode/index.vue b/ebike-operate/src/views/Produce/BikeQRCode/index.vue index dfaa17c..c8667c0 100644 --- a/ebike-operate/src/views/Produce/BikeQRCode/index.vue +++ b/ebike-operate/src/views/Produce/BikeQRCode/index.vue @@ -1,6 +1,5 @@ - - + + +const batchDownload = () => { + if( batchDownloadList.value.length === 0) { + message.error('请选择要下载的二维码') + return + } + + const urls = batchDownloadList.value.map(item => { + return { + base64QrCode:item.base64QrCode, + code:item.bikeCode + } + }); + batchDownloadQRcodes(urls) +} + + \ No newline at end of file diff --git a/ebike-operate/src/views/Produce/HelmetQRCode/index.vue b/ebike-operate/src/views/Produce/HelmetQRCode/index.vue index 44fd9e4..1c5e5e3 100644 --- a/ebike-operate/src/views/Produce/HelmetQRCode/index.vue +++ b/ebike-operate/src/views/Produce/HelmetQRCode/index.vue @@ -104,6 +104,17 @@ 绑定 + + + + 批量下载 + + +const batchDownload = () => { + if( batchDownloadList.value.length === 0) { + message.error('请选择要下载的二维码') + return + } + + const urls = batchDownloadList.value.map(item => { + return { + base64QrCode:item.base64QrCode, + code:item.helmetCode + } + }); + batchDownloadQRcodes(urls) +} + + \ No newline at end of file