下载模组更新,新增下载组件,下载监听改为全局,全量改为增量监听

This commit is contained in:
2025-08-31 06:41:46 +08:00
parent aa04f9d03f
commit ad5dfc64cb
17 changed files with 1662 additions and 285 deletions
+2 -2
View File
@@ -370,8 +370,8 @@ class ArtistService {
}
try {
// 发送API请求
const response = await axios(config);
// 使用auth实例的axiosInstance发送请求,这样可以利用自动token刷新机制
const response = await this.auth.axiosInstance(config);
const responseData = response.data;
// 对于GET请求,将响应数据缓存
+2 -2
View File
@@ -407,8 +407,8 @@ class ArtworkService {
}
}
// 发送API请求
const response = await axios(config);
// 使用auth实例的axiosInstance发送请求,这样可以利用自动token刷新机制
const response = await this.auth.axiosInstance(config);
const responseData = response.data;
// 对于GET请求,将响应数据缓存
+100
View File
@@ -98,6 +98,106 @@ class DownloadService {
};
}
/**
* 获取活跃任务(下载中或暂停)
*/
async getActiveTasks() {
return {
success: true,
data: this.taskManager.getActiveTasks(),
};
}
/**
* 获取任务摘要(用于快速状态检查)
*/
async getTasksSummary() {
const allTasks = this.taskManager.getAllTasks();
const activeTasks = this.taskManager.getActiveTasks();
const summary = {
total: allTasks.length,
active: activeTasks.length,
downloading: activeTasks.filter(t => t.status === 'downloading').length,
paused: activeTasks.filter(t => t.status === 'paused').length,
completed: allTasks.filter(t => t.status === 'completed').length,
failed: allTasks.filter(t => t.status === 'failed').length,
cancelled: allTasks.filter(t => t.status === 'cancelled').length,
partial: allTasks.filter(t => t.status === 'partial').length,
lastUpdate: Date.now()
};
return {
success: true,
data: summary,
};
}
/**
* 获取任务变更(增量更新)
*/
async getTasksChanges(since = null) {
const allTasks = this.taskManager.getAllTasks();
if (!since) {
// 如果没有since参数,返回所有活跃任务
return {
success: true,
data: {
tasks: this.taskManager.getActiveTasks(),
lastUpdate: Date.now()
},
};
}
// 过滤出自指定时间后有变更的任务
const changedTasks = allTasks.filter(task => {
const lastModified = Math.max(
new Date(task.created_at).getTime(),
task.updated_at ? new Date(task.updated_at).getTime() : 0,
task.end_time ? new Date(task.end_time).getTime() : 0
);
return lastModified > since;
});
return {
success: true,
data: {
tasks: changedTasks,
lastUpdate: Date.now()
},
};
}
/**
* 获取已完成任务(分页)
*/
async getCompletedTasks(offset = 0, limit = 50) {
const allTasks = this.taskManager.getAllTasks();
const completedTasks = allTasks.filter(task =>
['completed', 'failed', 'cancelled', 'partial'].includes(task.status)
);
// 按完成时间倒序排列
completedTasks.sort((a, b) => {
const timeA = a.end_time ? new Date(a.end_time).getTime() : 0;
const timeB = b.end_time ? new Date(b.end_time).getTime() : 0;
return timeB - timeA;
});
const paginatedTasks = completedTasks.slice(offset, offset + limit);
return {
success: true,
data: {
tasks: paginatedTasks,
total: completedTasks.length,
offset,
limit
},
};
}
async cancelTask(taskId) {
const task = this.taskManager.getTask(taskId);
if (!task) {
+47 -1
View File
@@ -5,6 +5,10 @@ class ProgressManager {
constructor() {
// 进度监听器: taskId -> listeners[]
this.progressListeners = new Map();
// 节流控制: taskId -> { lastUpdate, pending }
this.throttleControl = new Map();
// 节流间隔(毫秒)
this.throttleInterval = 100;
}
/**
@@ -29,14 +33,56 @@ class ProgressManager {
}
if (listeners.length === 0) {
this.progressListeners.delete(taskId);
// 清理节流控制
this.throttleControl.delete(taskId);
}
}
}
/**
* 通知进度更新
* 通知进度更新(带节流)
*/
notifyProgressUpdate(taskId, task) {
if (!this.progressListeners.has(taskId)) {
return;
}
const now = Date.now();
const throttleInfo = this.throttleControl.get(taskId);
// 如果是重要状态变更(完成、失败、取消),立即通知
const isImportantStatus = ['completed', 'failed', 'cancelled', 'partial', 'paused'].includes(task.status);
if (isImportantStatus) {
// 立即通知重要状态变更
this._executeListeners(taskId, task);
// 清理节流控制
this.throttleControl.delete(taskId);
return;
}
// 对于普通进度更新,使用节流
if (!throttleInfo || (now - throttleInfo.lastUpdate) >= this.throttleInterval) {
// 立即通知
this._executeListeners(taskId, task);
this.throttleControl.set(taskId, { lastUpdate: now, pending: false });
} else if (!throttleInfo.pending) {
// 延迟通知
throttleInfo.pending = true;
setTimeout(() => {
const currentThrottleInfo = this.throttleControl.get(taskId);
if (currentThrottleInfo && currentThrottleInfo.pending) {
this._executeListeners(taskId, task);
this.throttleControl.delete(taskId);
}
}, this.throttleInterval - (now - throttleInfo.lastUpdate));
}
}
/**
* 执行监听器(内部方法)
*/
_executeListeners(taskId, task) {
if (this.progressListeners.has(taskId)) {
const listeners = this.progressListeners.get(taskId);
listeners.forEach(listener => {