From b68de2e9bf83b318928ccdeef71915b6abd3dc6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=8C=E7=B3=96=E5=8C=85=E5=AD=90?= Date: Tue, 31 Mar 2026 22:23:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=AD=8C=E5=8D=95?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增歌单管理界面,支持添加和删除歌单 - 在MusicLibModel中添加musicCount字段显示歌曲数量 - 优化歌词编辑界面,添加加载状态提示 - 优化UI细节和路由视图加载时机 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/model/api/music.ts | 1 + src/static/common.less | 1 - src/views/Home.vue | 4 +- src/views/api/Music.vue | 84 +++++++++++++++++++++++++++++++++++++---- 4 files changed, 79 insertions(+), 11 deletions(-) diff --git a/src/model/api/music.ts b/src/model/api/music.ts index 5d0cefb..9642cbe 100644 --- a/src/model/api/music.ts +++ b/src/model/api/music.ts @@ -16,6 +16,7 @@ export interface MusicLibModel { _id: string name: string // 歌单名称 path: string // 歌单文件路径 + musicCount: number // 歌曲数量 } export interface MusicLyricModel { diff --git a/src/static/common.less b/src/static/common.less index 3c901f4..a4893ab 100644 --- a/src/static/common.less +++ b/src/static/common.less @@ -152,7 +152,6 @@ html, body, #app, .layout { .search-btn { margin-left: auto; display: flex; - gap: 8px; } } diff --git a/src/views/Home.vue b/src/views/Home.vue index 5361db1..9e595fe 100644 --- a/src/views/Home.vue +++ b/src/views/Home.vue @@ -40,8 +40,8 @@ -
- +
+ diff --git a/src/views/api/Music.vue b/src/views/api/Music.vue index 96ad225..044dd31 100644 --- a/src/views/api/Music.vue +++ b/src/views/api/Music.vue @@ -24,6 +24,7 @@
播放 上传音乐 + 歌单管理
搜索 重置 @@ -85,7 +86,7 @@
- + @@ -139,6 +140,31 @@ + + 添加歌单 + + + + + + + + + + + + + @@ -190,6 +216,10 @@ const currentMusic = ref() const lyricForm = ref() const musicUpload = ref() const player = ref() +const lyricLoading = ref(false) +const libDrawerVisible = ref(false) +const libTableData = ref<(MusicLibModel & { _isNew?: boolean })[]>([]) +const libSaving = ref(false) const lyricRuleValidate = { cloudId: [ @@ -266,13 +296,17 @@ function remove(row: MusicModel) { } async function updateLyric(row: MusicModel) { currentRow.value = { ...row } + lyricFormData.value = {} modifyLyricModal.value = true if (row.lyricId) { - const data = (await http.get('/api/v2/music/lyric/get', {params: {lyricId: row.lyricId}})) - data.cloudId = data.cloudId ? data.cloudId.toString() : null - lyricFormData.value = data - } else { - lyricFormData.value = {} + lyricLoading.value = true + try { + const data = await http.get('/api/v2/music/lyric/get', {params: {lyricId: row.lyricId}}) + data.cloudId = data.cloudId ? data.cloudId.toString() : null + lyricFormData.value = data + } finally { + lyricLoading.value = false + } } } async function saveLyric() { @@ -350,9 +384,43 @@ function musicPlay() { }) } +function loadLibs() { + return http.get('/api/v2/music/lib/list').then(data => { + musicLibs.value = data + libTableData.value = data.map((item: MusicLibModel) => ({ ...item })) + }) +} +function addLibRow() { + if (libTableData.value.some(item => (item as any)._isNew)) return + libTableData.value.unshift({ _id: '', name: '', path: '', musicCount: 0, _isNew: true }) +} +function cancelAddLib() { + libTableData.value = libTableData.value.filter(item => !(item as any)._isNew) +} +async function saveLib(row: MusicLibModel & { _isNew?: boolean }) { + if (!row.name || !row.path) { + ElMessage.warning('请输入歌单名称和路径') + return + } + libSaving.value = true + try { + await http.post('/api/v2/music/lib/add', { name: row.name, path: row.path }) + ElMessage.success('歌单创建成功') + await loadLibs() + } finally { + libSaving.value = false + } +} +function removeLib(row: MusicLibModel) { + ElMessageBox.confirm(`是否确认删除歌单「${row.name}」?`, '确认删除', { type: 'warning' }).then(async () => { + await http.delete('/api/v2/music/lib/delete', { params: { id: row._id } }) + ElMessage.success('歌单删除成功') + await loadLibs() + }).catch(() => {}) +} + // created -http.get('/api/v2/music/lib/list').then(data => { - musicLibs.value = data +loadLibs().then(() => { loadData() }) http.get('/api/v2/music/listExts').then(data => {