Skip to content

Commit 16a89af

Browse files
author
Taois
committed
feat: 小说下载器逻辑完善
1 parent 0e5f595 commit 16a89af

File tree

2 files changed

+162
-9
lines changed

2 files changed

+162
-9
lines changed

dashboard/src/components/downloader/NovelDownloader.vue

Lines changed: 120 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,44 @@
4343

4444
<!-- 过滤标签 -->
4545
<div class="filter-tabs">
46-
<a-radio-group v-model="activeFilter" type="button">
47-
<a-radio value="all">全部 ({{ totalTasks }})</a-radio>
48-
<a-radio value="downloading">下载中 ({{ downloadingTasks }})</a-radio>
49-
<a-radio value="completed">已完成 ({{ completedTasks }})</a-radio>
50-
<a-radio value="failed">失败 ({{ failedTasks }})</a-radio>
51-
<a-radio value="pending">等待中 ({{ pendingTasks }})</a-radio>
52-
</a-radio-group>
46+
<div class="filter-left">
47+
<a-radio-group v-model="activeFilter" type="button">
48+
<a-radio value="all">全部 ({{ totalTasks }})</a-radio>
49+
<a-radio value="downloading">下载中 ({{ downloadingTasks }})</a-radio>
50+
<a-radio value="completed">已完成 ({{ completedTasks }})</a-radio>
51+
<a-radio value="failed">失败 ({{ failedTasks }})</a-radio>
52+
<a-radio value="pending">等待中 ({{ pendingTasks }})</a-radio>
53+
</a-radio-group>
54+
</div>
55+
56+
<!-- 储存空间统计 -->
57+
<div class="storage-stats" v-if="downloadStore.tasks.length > 0">
58+
<div class="storage-info">
59+
<div class="storage-header">
60+
<icon-download class="storage-icon" />
61+
<span class="storage-title">本地储存空间</span>
62+
<a-tag
63+
:color="storageStats.isOverLimit ? 'red' : storageStats.isNearLimit ? 'orange' : 'green'"
64+
size="small"
65+
>
66+
{{ Math.round(storageStats.usagePercentage) }}%
67+
</a-tag>
68+
</div>
69+
<div class="storage-progress">
70+
<a-progress
71+
:percent="storageStats.usagePercentage"
72+
:color="storageStats.isOverLimit ? '#f53f3f' : storageStats.isNearLimit ? '#ff7d00' : '#00b42a'"
73+
:show-text="false"
74+
size="small"
75+
/>
76+
</div>
77+
<div class="storage-details">
78+
<span class="storage-used">已用: {{ storageStats.formattedUsed }}</span>
79+
<span class="storage-available">可用: {{ storageStats.formattedAvailable }}</span>
80+
<span class="storage-total">总计: {{ storageStats.formattedTotal }}</span>
81+
</div>
82+
</div>
83+
</div>
5384
</div>
5485

5586
<!-- 下载任务列表 -->
@@ -92,6 +123,7 @@
92123

93124
<script setup>
94125
import { ref, computed, onMounted, onUnmounted } from 'vue'
126+
import { useRouter } from 'vue-router'
95127
import { Message } from '@arco-design/web-vue'
96128
import {
97129
IconDownload,
@@ -102,6 +134,7 @@ import DownloadTaskItem from './DownloadTaskItem.vue'
102134
import AddDownloadTaskDialog from './AddDownloadTaskDialog.vue'
103135
import ChapterDetailsDialog from './ChapterDetailsDialog.vue'
104136
import { useDownloadStore } from '@/stores/downloadStore'
137+
import downloadService from '@/services/downloadService'
105138
106139
// Props
107140
const props = defineProps({
@@ -114,14 +147,16 @@ const props = defineProps({
114147
// Emits
115148
const emit = defineEmits(['close'])
116149
117-
// 下载状态管理
150+
// 路由和状态管理
151+
const router = useRouter()
118152
const downloadStore = useDownloadStore()
119153
120154
// 响应式数据
121155
const activeFilter = ref('all')
122156
const showAddTaskDialog = ref(false)
123157
const showChapterDialog = ref(false)
124158
const selectedTask = ref(null)
159+
const storageStats = ref({}) // 储存空间统计
125160
126161
// 计算属性
127162
const totalTasks = computed(() => downloadStore.tasks.length)
@@ -146,37 +181,48 @@ const currentSelectedTask = computed(() => {
146181
147182
// 方法
148183
const handleClose = () => {
149-
emit('close')
184+
// 使用Vue Router导航,返回上一页或首页
185+
if (window.history.length > 1) {
186+
router.go(-1)
187+
} else {
188+
router.push('/')
189+
}
150190
}
151191
152192
const handleAddTask = (taskData) => {
153193
downloadStore.addTask(taskData)
194+
updateStorageStats() // 更新储存统计
154195
showAddTaskDialog.value = false
155196
Message.success('下载任务已添加')
156197
}
157198
158199
const handleRetryTask = (taskId) => {
159200
downloadStore.retryTask(taskId)
201+
updateStorageStats() // 更新储存统计
160202
Message.info('正在重试下载任务')
161203
}
162204
163205
const handlePauseTask = (taskId) => {
164206
downloadStore.pauseTask(taskId)
207+
updateStorageStats() // 更新储存统计
165208
Message.info('下载任务已暂停')
166209
}
167210
168211
const handleResumeTask = (taskId) => {
169212
downloadStore.resumeTask(taskId)
213+
updateStorageStats() // 更新储存统计
170214
Message.info('下载任务已恢复')
171215
}
172216
173217
const handleCancelTask = (taskId) => {
174218
downloadStore.cancelTask(taskId)
219+
updateStorageStats() // 更新储存统计
175220
Message.info('下载任务已取消')
176221
}
177222
178223
const handleDeleteTask = (taskId) => {
179224
downloadStore.deleteTask(taskId)
225+
updateStorageStats() // 更新储存统计
180226
Message.success('下载任务已删除')
181227
}
182228
@@ -196,12 +242,19 @@ const handleRetryChapter = (taskId, chapterIndex) => {
196242
197243
const clearCompleted = () => {
198244
downloadStore.clearCompleted()
245+
updateStorageStats() // 更新储存统计
199246
Message.success('已清理完成的下载任务')
200247
}
201248
249+
// 更新储存空间统计
250+
const updateStorageStats = () => {
251+
storageStats.value = downloadService.getStorageStats()
252+
}
253+
202254
// 生命周期
203255
onMounted(() => {
204256
downloadStore.loadTasks()
257+
updateStorageStats() // 初始化储存统计
205258
})
206259
207260
onUnmounted(() => {
@@ -258,10 +311,68 @@ onUnmounted(() => {
258311
}
259312
260313
.filter-tabs {
314+
display: flex;
315+
justify-content: space-between;
316+
align-items: center;
261317
padding: 16px 24px;
262318
border-bottom: 1px solid var(--color-border-2);
263319
}
264320
321+
.filter-left {
322+
flex: 1;
323+
}
324+
325+
.storage-stats {
326+
min-width: 200px;
327+
}
328+
329+
.storage-info {
330+
display: flex;
331+
flex-direction: column;
332+
gap: 8px;
333+
}
334+
335+
.storage-header {
336+
display: flex;
337+
align-items: center;
338+
gap: 8px;
339+
}
340+
341+
.storage-icon {
342+
font-size: 14px;
343+
color: var(--color-text-2);
344+
}
345+
346+
.storage-title {
347+
font-size: 12px;
348+
color: var(--color-text-2);
349+
font-weight: 500;
350+
}
351+
352+
.storage-progress {
353+
width: 100%;
354+
}
355+
356+
.storage-details {
357+
display: flex;
358+
justify-content: space-between;
359+
font-size: 11px;
360+
color: var(--color-text-3);
361+
}
362+
363+
.storage-used {
364+
color: var(--color-text-1);
365+
font-weight: 500;
366+
}
367+
368+
.storage-available {
369+
color: var(--color-text-2);
370+
}
371+
372+
.storage-total {
373+
color: var(--color-text-2);
374+
}
375+
265376
.download-list {
266377
flex: 1;
267378
overflow-y: auto;

dashboard/src/services/downloadService.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,48 @@ class DownloadService {
475475
}
476476
}
477477

478+
// 获取储存空间统计
479+
getStorageStats() {
480+
const STORAGE_LIMIT = 100 * 1024 * 1024 // 100MB 限制,与书画柜独立
481+
482+
// 计算所有下载任务的总大小
483+
const usedBytes = this.getAllTasks().reduce((total, task) => {
484+
return total + (task.downloadedSize || 0)
485+
}, 0)
486+
487+
const availableBytes = Math.max(0, STORAGE_LIMIT - usedBytes)
488+
const usagePercentage = (usedBytes / STORAGE_LIMIT) * 100
489+
490+
return {
491+
usedBytes,
492+
availableBytes,
493+
totalBytes: STORAGE_LIMIT,
494+
usagePercentage: Math.min(100, usagePercentage),
495+
isNearLimit: usagePercentage > 80,
496+
isOverLimit: usagePercentage >= 100,
497+
formattedUsed: this.formatFileSize(usedBytes),
498+
formattedAvailable: this.formatFileSize(availableBytes),
499+
formattedTotal: this.formatFileSize(STORAGE_LIMIT)
500+
}
501+
}
502+
503+
// 格式化文件大小
504+
formatFileSize(bytes) {
505+
if (bytes === 0) return '0 B'
506+
507+
const k = 1024
508+
const sizes = ['B', 'KB', 'MB', 'GB']
509+
const i = Math.floor(Math.log(bytes) / Math.log(k))
510+
511+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
512+
}
513+
514+
// 检查是否可以添加新任务(基于大小限制)
515+
canAddTask(estimatedSize = 0) {
516+
const storageStats = this.getStorageStats()
517+
return estimatedSize <= storageStats.availableBytes
518+
}
519+
478520
// 保存任务到本地存储
479521
saveTasksToStorage() {
480522
try {

0 commit comments

Comments
 (0)