feat(download): 新增未保存下载设置时的确认对话框 (#507)

- feat(download): 关闭下载设置抽屉时检测未保存更改,提供取消/放弃/保存选项
- fix: 自动播放首次暂停无法暂停,移除不必要的 isFirstPlay 检查
- fix: 歌手详情路由添加 props key,修复跳转歌手详情不生效问题
- i18n: 添加 download.save.* 翻译(5 种语言)

Co-Authored-By: 心妄 <1661272893@qq.com>
This commit is contained in:
Vanilla-puree
2026-04-08 19:28:27 +08:00
committed by alger
parent ad2df12957
commit 0ab784024c
8 changed files with 104 additions and 4 deletions

View File

@@ -58,6 +58,14 @@ export default {
success: 'Download records cleared',
failed: 'Failed to clear download records'
},
save: {
title: 'Save Settings',
message: 'Current download settings are not saved. Do you want to save the changes?',
confirm: 'Save',
cancel: 'Cancel',
discard: 'Discard',
saveSuccess: 'Download settings saved'
},
message: {
downloadComplete: '{filename} download completed',
downloadFailed: '{filename} download failed: {error}'

View File

@@ -58,6 +58,14 @@ export default {
success: 'ダウンロード記録をクリアしました',
failed: 'ダウンロード記録のクリアに失敗しました'
},
save: {
title: '設定を保存',
message: '現在のダウンロード設定が保存されていません。変更を保存しますか?',
confirm: '保存',
cancel: 'キャンセル',
discard: '破棄',
saveSuccess: 'ダウンロード設定を保存しました'
},
message: {
downloadComplete: '{filename}のダウンロードが完了しました',
downloadFailed: '{filename}のダウンロードに失敗しました: {error}'

View File

@@ -58,6 +58,14 @@ export default {
success: '다운로드 기록이 지워졌습니다',
failed: '다운로드 기록 삭제에 실패했습니다'
},
save: {
title: '설정 저장',
message: '현재 다운로드 설정이 저장되지 않았습니다. 변경 사항을 저장하시겠습니까?',
confirm: '저장',
cancel: '취소',
discard: '포기',
saveSuccess: '다운로드 설정이 저장됨'
},
message: {
downloadComplete: '{filename} 다운로드 완료',
downloadFailed: '{filename} 다운로드 실패: {error}'

View File

@@ -57,6 +57,14 @@ export default {
success: '下载记录已清空',
failed: '清空下载记录失败'
},
save: {
title: '保存设置',
message: '当前下载设置未保存,是否保存更改?',
confirm: '保存',
cancel: '取消',
discard: '放弃',
saveSuccess: '下载设置已保存'
},
message: {
downloadComplete: '{filename} 下载完成',
downloadFailed: '{filename} 下载失败: {error}'

View File

@@ -57,6 +57,14 @@ export default {
success: '下載記錄已清空',
failed: '清空下載記錄失敗'
},
save: {
title: '儲存設定',
message: '目前下載設定尚未儲存,是否儲存變更?',
confirm: '儲存',
cancel: '取消',
discard: '放棄',
saveSuccess: '下載設定已儲存'
},
message: {
downloadComplete: '{filename} 下載完成',
downloadFailed: '{filename} 下載失敗: {error}'

View File

@@ -53,7 +53,8 @@ const otherRouter = [
showInMenu: false,
back: true
},
component: () => import('@/views/artist/detail.vue')
component: () => import('@/views/artist/detail.vue'),
props: (route) => ({ key: route.params.id })
},
{
path: '/music-list/:id?',

View File

@@ -585,8 +585,7 @@ export const usePlaylistStore = defineStore(
// Toggle play/pause for current song
if (
playerCore.playMusic.id === song.id &&
playerCore.playMusic.playMusicUrl === song.playMusicUrl &&
!song.isFirstPlay
playerCore.playMusic.playMusicUrl === song.playMusicUrl
) {
if (playerCore.play) {
playerCore.setPlayMusic(false);

View File

@@ -325,8 +325,38 @@
@positive-click="clearDownloadRecords"
/>
<!-- 未保存下载设置确认对话框 -->
<n-modal
v-model:show="showNotSaveConfirm"
preset="dialog"
type="warning"
:z-index="3200"
:title="t('download.save.title')"
:content="t('download.save.message')"
:positive-text="t('download.save.confirm')"
:negative-text="t('download.save.discard')"
@positive-click="saveDownloadSettings"
@negative-click="discardDownloadSettings"
>
<template #action>
<n-button @click="showNotSaveConfirm = false">{{ t('download.save.cancel') }}</n-button>
<n-button type="error" @click="discardDownloadSettings">{{
t('download.save.discard')
}}</n-button>
<n-button type="primary" @click="saveDownloadSettings">{{
t('download.save.confirm')
}}</n-button>
</template>
</n-modal>
<!-- 下载设置抽屉 -->
<n-drawer v-model:show="showSettingsDrawer" :width="400" placement="right">
<n-drawer
:show="showSettingsDrawer"
:width="400"
placement="right"
:z-index="3100"
@update:show="handleDrawerUpdate"
>
<n-drawer-content :title="t('download.settingsPanel.title')" closable>
<div class="download-settings-content space-y-8 py-4">
<!-- Path Section -->
@@ -705,12 +735,40 @@ const clearDownloadRecords = async () => {
// ── Download settings ───────────────────────────────────────────────────────
const showSettingsDrawer = ref(false);
const showNotSaveConfirm = ref(false);
const downloadSettings = ref({
path: '',
nameFormat: '{songName} - {artistName}',
separator: ' - ',
saveLyric: false
});
const originalDownloadSettings = ref({ ...downloadSettings.value });
watch(showSettingsDrawer, (newVal) => {
if (newVal) {
originalDownloadSettings.value = { ...downloadSettings.value };
}
});
const handleDrawerUpdate = (show: boolean) => {
if (show) {
showSettingsDrawer.value = true;
return;
}
const isModified =
JSON.stringify(downloadSettings.value) !== JSON.stringify(originalDownloadSettings.value);
if (isModified) {
showNotSaveConfirm.value = true;
} else {
showSettingsDrawer.value = false;
}
};
const discardDownloadSettings = () => {
downloadSettings.value = { ...originalDownloadSettings.value };
showNotSaveConfirm.value = false;
showSettingsDrawer.value = false;
};
const formatComponents = ref([
{ id: 1, type: 'songName' },
@@ -824,7 +882,9 @@ const saveDownloadSettings = () => {
downloadStore.refreshCompleted();
}
originalDownloadSettings.value = { ...downloadSettings.value };
message.success(t('download.settingsPanel.saveSuccess'));
showNotSaveConfirm.value = false;
showSettingsDrawer.value = false;
};