Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions electron/main/ipc/ipc-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,10 +379,10 @@ const initFileIpc = (): void => {
songData?: any;
skipIfExist?: boolean;
} = {
fileName: "未知文件名",
fileType: "mp3",
path: app.getPath("downloads"),
},
fileName: "未知文件名",
fileType: "mp3",
path: app.getPath("downloads"),
},
): Promise<{ status: "success" | "skipped" | "error"; message?: string }> => {
try {
// 获取窗口
Expand Down
12 changes: 11 additions & 1 deletion src/components/Menu/SongListMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import type { SongType } from "@/types/main";
import { NAlert, type DropdownOption } from "naive-ui";
import { useStatusStore, useLocalStore, useDataStore, useMusicStore } from "@/stores";
import DownloadManager from "@/utils/downloadManager";
import { renderIcon, copyData } from "@/utils/helper";
import { deleteCloudSong, importCloudSong } from "@/api/cloud";
import {
Expand Down Expand Up @@ -74,6 +75,8 @@ const openDropdown = (
const isCurrent = statusStore.playIndex === index;
// 是否为用户歌单
const isUserPlaylist = !!playListId && userPlaylistsData.some((pl) => pl.id === playListId);
// 是否正在下载或下载失败
const isDownloading = dataStore.downloadingSongs.some((item) => item.song.id === song.id);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

仅使用一个布尔值 isDownloading 来判断状态过于宽泛。为了在菜单项中实现更精细的逻辑控制(例如,仅在下载失败或卡住时显示重试),建议获取完整的下载信息对象。

    const downloadInfo = dataStore.downloadingSongs.find((item) => item.song.id === song.id);
    const isDownloading = !!downloadInfo;

// 生成菜单
nextTick().then(() => {
dropdownOptions.value = [
Expand Down Expand Up @@ -246,10 +249,17 @@ const openDropdown = (
{
key: "download",
label: "下载歌曲",
show: !isLocal && type === "song",
show: !isLocal && type === "song" && !isDownloading,
props: { onClick: () => openDownloadSong(song) },
icon: renderIcon("Download"),
},
{
key: "retry-download",
label: "重试下载",
show: isDownloading,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

“重试下载”选项应该只在下载失败或卡在0%时才可用。对一个正在正常进行的下载提供重试选项会给用户带来困惑。使用上一个建议中获取的 downloadInfo 对象,我们可以让这个显示条件更精确。

          show: downloadInfo && (downloadInfo.status === "failed" || downloadInfo.progress === 0),

props: { onClick: () => DownloadManager.retryDownload(song.id) },
icon: renderIcon("Refresh"),
},
];
// 显示菜单
dropdownX.value = e.clientX;
Expand Down
1 change: 0 additions & 1 deletion src/components/Setting/LocalSetting.vue
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@
</template>

<script setup lang="ts">
import { computed } from "vue";
import { useSettingStore } from "@/stores";
import { changeLocalLyricPath, changeLocalMusicPath } from "@/utils/helper";
import { songLevelData, getSongLevelsData } from "@/utils/meta";
Expand Down
43 changes: 27 additions & 16 deletions src/stores/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ interface ListState {
song: SongType;
/** 音质 */
quality: SongLevelType;
/** 状态:下载中 / 失败 */
status: "downloading" | "failed";
/** 状态:下载中 / 等待中 / 失败 */
status: "downloading" | "waiting" | "failed";
/** 下载进度 */
progress: number;
/** 已传输大小 */
Expand Down Expand Up @@ -350,14 +350,23 @@ export const useDataStore = defineStore("data", {
this.downloadingSongs.push({
song: cloneDeep(song),
quality,
status: "downloading",
status: "waiting",
progress: 0,
transferred: "0MB",
totalSize: "0MB",
});
// 保存到本地存储
musicDB.setItem("downloadingSongs", cloneDeep(this.downloadingSongs));
},
// 更新下载状态
updateDownloadStatus(songId: number, status: "downloading" | "waiting" | "failed") {
const index = this.downloadingSongs.findIndex((item) => item.song.id === songId);
if (index !== -1) {
this.downloadingSongs[index].status = status;
// 强制触发响应式更新 (Fix: 下一首歌曲状态更新UI不变化的问题)
this.downloadingSongs = [...this.downloadingSongs];
}
},
// 更新下载进度
updateDownloadProgress(
songId: number,
Expand All @@ -370,7 +379,7 @@ export const useDataStore = defineStore("data", {
item.progress = progress;
item.transferred = transferred;
item.totalSize = totalSize;
// 进度更新过于频繁,不再实时保存到本地存储,仅在添加/删除时保存
// 进度更新过于频繁,不需要强制更新整个数组,以免影响性能
}
},
// 移除正在下载的歌曲(下载失败时)
Expand All @@ -383,23 +392,25 @@ export const useDataStore = defineStore("data", {
},
// 标记下载失败(保留在列表中)
markDownloadFailed(songId: number) {
const item = this.downloadingSongs.find((item) => item.song.id === songId);
if (item) {
item.status = "failed";
item.progress = 0;
item.transferred = "0MB";
item.totalSize = "0MB";
const index = this.downloadingSongs.findIndex((item) => item.song.id === songId);
if (index !== -1) {
this.downloadingSongs[index].status = "failed";
this.downloadingSongs[index].progress = 0;
this.downloadingSongs[index].transferred = "0MB";
this.downloadingSongs[index].totalSize = "0MB";
this.downloadingSongs = [...this.downloadingSongs];
musicDB.setItem("downloadingSongs", cloneDeep(this.downloadingSongs));
}
},
// 重置下载任务状态(用于重试)
resetDownloadingSong(songId: number) {
const item = this.downloadingSongs.find((item) => item.song.id === songId);
if (item) {
item.status = "downloading";
item.progress = 0;
item.transferred = "0MB";
item.totalSize = "0MB";
const index = this.downloadingSongs.findIndex((item) => item.song.id === songId);
if (index !== -1) {
this.downloadingSongs[index].status = "waiting";
this.downloadingSongs[index].progress = 0;
this.downloadingSongs[index].transferred = "0MB";
this.downloadingSongs[index].totalSize = "0MB";
this.downloadingSongs = [...this.downloadingSongs];
}
},
},
Expand Down
21 changes: 19 additions & 2 deletions src/utils/downloadManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,17 @@ class DownloadManager {
const total = (totalBytes / 1024 / 1024).toFixed(2) + "MB";
dataStore.updateDownloadProgress(
song.id,
Number((percent * 100).toFixed(0)),
Number((percent * 100).toFixed(1)),
transferred,
total,
);
};
removeListener = window.electron.ipcRenderer.on("download-progress", progressHandler);
}

// 更新状态为下载中
dataStore.updateDownloadStatus(song.id, "downloading");

// 开始下载
try {
const result = await this.processDownload({
Expand Down Expand Up @@ -319,14 +322,28 @@ class DownloadManager {
if (!task) return;

// 重置任务状态与进度
dataStore.resetDownloadingSong(songId);
dataStore.updateDownloadStatus(songId, "downloading");
// 重置进度信息
dataStore.updateDownloadProgress(songId, 0, "0MB", "0MB");

// 重新加入队列
this.queue.push({ song: task.song, quality: task.quality });

// 继续处理队列
this.processQueue();
}

/**
* 重试所有下载任务
*/
public retryAllDownloads() {
const dataStore = useDataStore();
const songsToRetry = dataStore.downloadingSongs.map((item) => item.song.id);

songsToRetry.forEach((id) => {
this.retryDownload(id);
});
}
}

export default DownloadManager.getInstance();
Loading