|
@@ -211,56 +211,80 @@ class CommonHelper
|
|
|
|
|
|
$('.downloadVideo').on('click', function(e) {
|
|
|
e.preventDefault();
|
|
|
- const videoUrl = $(this).attr('videoUrl');
|
|
|
+ const button = $(this);
|
|
|
+ const videoUrl = button.attr('videoUrl');
|
|
|
|
|
|
- const progressBar = $('<div class=\"progress-bar\">').appendTo('body');
|
|
|
+ // 使用 Dcat Admin 内置 loading 组件
|
|
|
+ const loading = Dcat.loading('<i class=\"feather icon-download-cloud\"></i> downloading...');
|
|
|
|
|
|
fetch(videoUrl, {
|
|
|
- headers: new Headers({'Origin': location.origin}),
|
|
|
+ headers: new Headers({
|
|
|
+ 'Origin': location.origin,
|
|
|
+ 'X-CSRF-TOKEN': Dcat.token // 集成 CSRF 保护[7](@ref)
|
|
|
+ }),
|
|
|
mode: 'cors'
|
|
|
- })
|
|
|
- .then(response => {
|
|
|
- if (!response.ok) throw new Error('HTTP状态码异常');
|
|
|
+ }).then(response => {
|
|
|
+ if (!response.ok) throw new Error(`HTTP \${response.status}`);
|
|
|
+
|
|
|
+ // 动态创建进度条组件
|
|
|
+ const progress = new Dcat.Progress({
|
|
|
+ title: '下载进度',
|
|
|
+ showCancel: true,
|
|
|
+ onCancel: () => controller.abort()
|
|
|
+ });
|
|
|
+
|
|
|
const reader = response.body.getReader();
|
|
|
+ const controller = new AbortController();
|
|
|
const contentLength = +response.headers.get('Content-Length');
|
|
|
let receivedLength = 0;
|
|
|
const chunks = [];
|
|
|
|
|
|
- // 流式处理大文件
|
|
|
- function processChunk({ done, value }) {
|
|
|
- if (done) {
|
|
|
- const blob = new Blob(chunks);
|
|
|
- const filename = videoUrl.split('/').pop() || 'video.mp4';
|
|
|
- const objectUrl = URL.createObjectURL(blob);
|
|
|
+ // 流式处理优化
|
|
|
+ const processChunk = ({ done, value }) => {
|
|
|
+ if (done || progress.canceled) {
|
|
|
+ if (!progress.canceled) {
|
|
|
+ const blob = new Blob(chunks);
|
|
|
+ const filename = videoUrl.split('/').pop() || 'video.mp4';
|
|
|
+ const link = document.createElement('a');
|
|
|
|
|
|
- // 使用FileSaver增强兼容性(网页8方案)
|
|
|
- if (window.saveAs) {
|
|
|
- saveAs(objectUrl, filename);
|
|
|
- } else {
|
|
|
- const tempLink = document.createElement('a');
|
|
|
- tempLink.href = objectUrl;
|
|
|
- tempLink.download = filename;
|
|
|
- tempLink.click();
|
|
|
+ // 集成 Dcat 文件管理器[6](@ref)
|
|
|
+ Dcat.handleFileDownload(blob, filename);
|
|
|
}
|
|
|
-
|
|
|
- progressBar.remove();
|
|
|
+ progress.close();
|
|
|
+ loading.close();
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
chunks.push(value);
|
|
|
receivedLength += value.length;
|
|
|
- progressBar.css('width', `\${(receivedLength/contentLength)*100}%`);
|
|
|
+ progress.update({
|
|
|
+ percent: Math.round((receivedLength / contentLength) * 100),
|
|
|
+ statusText: `\${formatBytes(receivedLength)} / \${formatBytes(contentLength)}`
|
|
|
+ });
|
|
|
+
|
|
|
return reader.read().then(processChunk);
|
|
|
- }
|
|
|
+ };
|
|
|
|
|
|
return reader.read().then(processChunk);
|
|
|
- })
|
|
|
- .catch(error => {
|
|
|
- console.error('下载失败:', error);
|
|
|
- alert('视频下载失败,请检查网络或文件有效性');
|
|
|
+ }).catch(error => {
|
|
|
+ loading.close();
|
|
|
+ Dcat.error(`下载失败: \${error.message}`);
|
|
|
+ console.error('Download Error:', error);
|
|
|
});
|
|
|
});
|
|
|
|
|
|
+// 字节单位转换工具函数
|
|
|
+function formatBytes(bytes) {
|
|
|
+ const units = ['B', 'KB', 'MB', 'GB'];
|
|
|
+ let i = 0;
|
|
|
+ while (bytes >= 1024 && i < units.length - 1) {
|
|
|
+ bytes /= 1024;
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ return `\${bytes.toFixed(1)} \${units[i]}`;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
// 点击关闭按钮关闭视频
|
|
|
$('.close-btn').on('click', function() {
|
|
|
$('#videoPopup').css('display', 'none');
|