[add] 新增无人机模块后端项目
[refactor] 重构后端项目
This commit is contained in:
189
drone/ruoyi-core/src/main/resources/index.html
Normal file
189
drone/ruoyi-core/src/main/resources/index.html
Normal file
@ -0,0 +1,189 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Download Files as ZIP</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
width: 300px;
|
||||
padding: 8px;
|
||||
margin-bottom: 10px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 10px 20px;
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
background-color: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
#progress-container {
|
||||
display: none;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
progress {
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
#progress-text {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.url-input-group {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Download Files as ZIP</h1>
|
||||
|
||||
<div id="url-container">
|
||||
<div class="url-input-group">
|
||||
<input type="text" class="url-input" placeholder="Enter file URL here">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="add-url-btn">Add URL</button>
|
||||
<br><br>
|
||||
<button id="download-btn" onclick="downloadFilesAsZip()">Download All as ZIP</button>
|
||||
|
||||
<div id="progress-container">
|
||||
<progress id="progress-bar" value="0" max="100"></progress>
|
||||
<div id="progress-text">0%</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js"></script>
|
||||
<script>
|
||||
document.getElementById('add-url-btn').addEventListener('click', function() {
|
||||
const urlContainer = document.getElementById('url-container');
|
||||
const newInput = document.createElement('div');
|
||||
newInput.className = 'url-input-group';
|
||||
newInput.innerHTML = '<input type="text" class="url-input" placeholder="Enter file URL here">';
|
||||
urlContainer.appendChild(newInput);
|
||||
});
|
||||
|
||||
async function downloadFilesAsZip() {
|
||||
const urlInputs = document.querySelectorAll('.url-input');
|
||||
const urls = Array.from(urlInputs).map(input => input.value).filter(url => url !== '');
|
||||
|
||||
if (urls.length === 0) {
|
||||
alert('Please enter at least one valid URL.');
|
||||
return;
|
||||
}
|
||||
|
||||
const downloadBtn = document.getElementById('download-btn');
|
||||
const progressBar = document.getElementById('progress-bar');
|
||||
const progressText = document.getElementById('progress-text');
|
||||
const progressContainer = document.getElementById('progress-container');
|
||||
|
||||
downloadBtn.disabled = true;
|
||||
progressContainer.style.display = 'block';
|
||||
|
||||
const zip = new JSZip();
|
||||
let totalSize = 0;
|
||||
let loaded = 0;
|
||||
|
||||
const progressMap = new Map(); // 记录每个文件的进度
|
||||
|
||||
// 更新总进度函数
|
||||
const updateProgress = () => {
|
||||
const totalLoaded = Array.from(progressMap.values()).reduce((acc, val) => acc + val, 0);
|
||||
const totalProgress = totalLoaded / urls.length;
|
||||
progressBar.value = totalProgress;
|
||||
progressText.textContent = `${Math.round(totalProgress)}%`;
|
||||
};
|
||||
|
||||
// 并行处理所有文件的下载
|
||||
const fetchPromises = urls.map(async (url, index) => {
|
||||
console.log(`Starting download for: ${url}`);
|
||||
const response = await fetch(url);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to download file: ${url}`);
|
||||
}
|
||||
|
||||
const contentLength = response.headers.get('content-length');
|
||||
let fileSize = 0;
|
||||
if (contentLength) {
|
||||
fileSize = parseInt(contentLength, 10);
|
||||
}
|
||||
|
||||
const reader = response.body.getReader();
|
||||
const chunks = [];
|
||||
let receivedLength = 0;
|
||||
|
||||
// 读取文件流并更新进度
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
chunks.push(value);
|
||||
receivedLength += value.length;
|
||||
|
||||
// 记录单个文件的下载进度
|
||||
const fileProgress = (receivedLength / fileSize) * 100;
|
||||
progressMap.set(index, fileProgress);
|
||||
updateProgress(); // 更新总进度
|
||||
}
|
||||
|
||||
const blob = new Blob(chunks); // 合并所有块,生成一个Blob
|
||||
const filename = encodeURIComponent(url.split('/').pop()); // 确保文件名安全
|
||||
zip.file(filename, blob); // 将文件添加到ZIP中
|
||||
});
|
||||
|
||||
try {
|
||||
await Promise.all(fetchPromises); // 等待所有文件下载完成
|
||||
|
||||
// 强制进度到100%
|
||||
progressBar.value = 100;
|
||||
progressText.textContent = '100%';
|
||||
|
||||
// 生成 ZIP 文件并触发下载
|
||||
progressText.textContent = 'Packing ZIP...';
|
||||
const zipBlob = await zip.generateAsync({ type: 'blob' });
|
||||
const zipName = 'downloaded_files.zip';
|
||||
const zipUrl = URL.createObjectURL(zipBlob);
|
||||
const a = document.createElement('a');
|
||||
a.href = zipUrl;
|
||||
a.download = zipName;
|
||||
a.click();
|
||||
URL.revokeObjectURL(zipUrl); // 清理 URL
|
||||
|
||||
// 重置 UI
|
||||
progressBar.value = 0;
|
||||
progressText.textContent = '0%';
|
||||
progressContainer.style.display = 'none';
|
||||
downloadBtn.disabled = false;
|
||||
} catch (error) {
|
||||
console.error('Error during file download or ZIP generation:', error);
|
||||
alert('Error during file download or ZIP generation: ' + error.message);
|
||||
downloadBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user