diff --git a/src/i18n/lang/en-US/common.ts b/src/i18n/lang/en-US/common.ts
index 98b4c9e..4802692 100644
--- a/src/i18n/lang/en-US/common.ts
+++ b/src/i18n/lang/en-US/common.ts
@@ -27,6 +27,7 @@ export default {
refresh: 'Refresh',
retry: 'Retry',
reset: 'Reset',
+ back: 'Back',
copySuccess: 'Copied to clipboard',
copyFailed: 'Copy failed',
validation: {
diff --git a/src/i18n/lang/en-US/comp.ts b/src/i18n/lang/en-US/comp.ts
index 6434031..ef03a28 100644
--- a/src/i18n/lang/en-US/comp.ts
+++ b/src/i18n/lang/en-US/comp.ts
@@ -120,5 +120,65 @@ export default {
addToPlaylistSuccess: 'Add to Playlist Success',
operationFailed: 'Operation Failed',
songsAlreadyInPlaylist: 'Songs already in playlist'
+ },
+ playlist: {
+ import: {
+ button: 'Import Playlist',
+ title: 'Import Playlist',
+ description: 'Import playlists via metadata, text, or links',
+ linkTab: 'Import by Link',
+ textTab: 'Import by Text',
+ localTab: 'Import by Metadata',
+ linkPlaceholder: 'Enter playlist links, one per line',
+ textPlaceholder: 'Enter song information in format: Song Name Artist Name',
+ localPlaceholder: 'Enter song metadata in JSON format',
+ linkTips: 'Supported link sources:',
+ linkTip1: 'Copy links after sharing playlists to WeChat/Weibo/QQ',
+ linkTip2: 'Directly copy playlist/profile links',
+ linkTip3: 'Directly copy article links',
+ textTips: 'Enter song information, one song per line',
+ textFormat: 'Format: Song Name Artist Name',
+ localTips: 'Add song metadata',
+ localFormat: 'Format example:',
+ songNamePlaceholder: 'Song Name',
+ artistNamePlaceholder: 'Artist Name',
+ albumNamePlaceholder: 'Album Name',
+ addSongButton: 'Add Song',
+ addLinkButton: 'Add Link',
+ importToStarPlaylist: 'Import to My Favorite Music',
+ playlistNamePlaceholder: 'Enter playlist name',
+ importButton: 'Start Import',
+ emptyLinkWarning: 'Please enter playlist links',
+ emptyTextWarning: 'Please enter song information',
+ emptyLocalWarning: 'Please enter song metadata',
+ invalidJsonFormat: 'Invalid JSON format',
+ importSuccess: 'Import task created successfully',
+ importFailed: 'Import failed',
+ importStatus: 'Import Status',
+ refresh: 'Refresh',
+ taskId: 'Task ID',
+ status: 'Status',
+ successCount: 'Success Count',
+ failReason: 'Failure Reason',
+ unknownError: 'Unknown error',
+ statusPending: 'Pending',
+ statusProcessing: 'Processing',
+ statusSuccess: 'Success',
+ statusFailed: 'Failed',
+ statusUnknown: 'Unknown',
+ taskList: 'Task List',
+ taskListTitle: 'Import Task List',
+ action: 'Action',
+ select: 'Select',
+ fetchTaskListFailed: 'Failed to fetch task list',
+ noTasks: 'No import tasks',
+ clearTasks: 'Clear Tasks',
+ clearTasksConfirmTitle: 'Confirm Clear',
+ clearTasksConfirmContent: 'Are you sure you want to clear all import task records? This action cannot be undone.',
+ confirm: 'Confirm',
+ cancel: 'Cancel',
+ clearTasksSuccess: 'Task list cleared',
+ clearTasksFailed: 'Failed to clear task list'
+ }
}
};
diff --git a/src/i18n/lang/zh-CN/common.ts b/src/i18n/lang/zh-CN/common.ts
index 6b3fe42..746a97f 100644
--- a/src/i18n/lang/zh-CN/common.ts
+++ b/src/i18n/lang/zh-CN/common.ts
@@ -27,6 +27,7 @@ export default {
refresh: '刷新',
retry: '重试',
reset: '重置',
+ back: '返回',
copySuccess: '已复制到剪贴板',
copyFailed: '复制失败',
validation: {
diff --git a/src/i18n/lang/zh-CN/comp.ts b/src/i18n/lang/zh-CN/comp.ts
index f494fc6..2e666ef 100644
--- a/src/i18n/lang/zh-CN/comp.ts
+++ b/src/i18n/lang/zh-CN/comp.ts
@@ -118,5 +118,65 @@ export default {
addToPlaylist: '添加到播放列表',
addToPlaylistSuccess: '添加到播放列表成功',
songsAlreadyInPlaylist: '歌曲已存在于播放列表中'
+ },
+ playlist: {
+ import: {
+ button: '歌单导入',
+ title: '歌单导入',
+ description: '支持通过元数据/文字/链接三种方式导入歌单',
+ linkTab: '链接导入',
+ textTab: '文字导入',
+ localTab: '元数据导入',
+ linkPlaceholder: '请输入歌单链接,每行一个',
+ textPlaceholder: '请输入歌曲信息,格式为:歌曲名 歌手名',
+ localPlaceholder: '请输入JSON格式的歌曲元数据',
+ linkTips: '支持的链接来源:',
+ linkTip1: '将歌单分享到微信/微博/QQ后复制链接',
+ linkTip2: '直接复制歌单/个人主页链接',
+ linkTip3: '直接复制文章链接',
+ textTips: '请输入歌曲信息,每行一首歌',
+ textFormat: '格式:歌曲名 歌手名',
+ localTips: '请添加歌曲元数据',
+ localFormat: '格式示例:',
+ songNamePlaceholder: '歌曲名称',
+ artistNamePlaceholder: '艺术家名称',
+ albumNamePlaceholder: '专辑名称',
+ addSongButton: '添加歌曲',
+ addLinkButton: '添加链接',
+ importToStarPlaylist: '导入到我喜欢的音乐',
+ playlistNamePlaceholder: '请输入歌单名称',
+ importButton: '开始导入',
+ emptyLinkWarning: '请输入歌单链接',
+ emptyTextWarning: '请输入歌曲信息',
+ emptyLocalWarning: '请输入歌曲元数据',
+ invalidJsonFormat: 'JSON格式不正确',
+ importSuccess: '导入任务创建成功',
+ importFailed: '导入失败',
+ importStatus: '导入状态',
+ refresh: '刷新',
+ taskId: '任务ID',
+ status: '状态',
+ successCount: '成功数量',
+ failReason: '失败原因',
+ unknownError: '未知错误',
+ statusPending: '等待处理',
+ statusProcessing: '处理中',
+ statusSuccess: '导入成功',
+ statusFailed: '导入失败',
+ statusUnknown: '未知状态',
+ taskList: '任务列表',
+ taskListTitle: '导入任务列表',
+ action: '操作',
+ select: '选择',
+ fetchTaskListFailed: '获取任务列表失败',
+ noTasks: '暂无导入任务',
+ clearTasks: '清除任务',
+ clearTasksConfirmTitle: '确认清除',
+ clearTasksConfirmContent: '确定要清除所有导入任务记录吗?此操作不可恢复。',
+ confirm: '确认',
+ cancel: '取消',
+ clearTasksSuccess: '任务列表已清除',
+ clearTasksFailed: '清除任务列表失败'
+ }
}
};
diff --git a/src/renderer/api/playlist.ts b/src/renderer/api/playlist.ts
new file mode 100644
index 0000000..9de168b
--- /dev/null
+++ b/src/renderer/api/playlist.ts
@@ -0,0 +1,27 @@
+import request from '@/utils/request';
+
+/**
+ * 歌单导入 - 元数据/文字/链接导入
+ * @param params 导入参数
+ */
+export function importPlaylist(params: {
+ local?: string;
+ text?: string;
+ link?: string;
+ importStarPlaylist?: boolean;
+ playlistName?: string;
+}) {
+ return request.post('/playlist/import/name/task/create', params);
+}
+
+/**
+ * 歌单导入 - 任务状态
+ * @param id 任务ID
+ */
+export function getImportTaskStatus(id: string | number) {
+ return request({
+ url: '/playlist/import/task/status',
+ method: 'get',
+ params: { id }
+ });
+}
\ No newline at end of file
diff --git a/src/renderer/components.d.ts b/src/renderer/components.d.ts
index 0c4f1b1..c1c31c1 100644
--- a/src/renderer/components.d.ts
+++ b/src/renderer/components.d.ts
@@ -13,6 +13,7 @@ declare module 'vue' {
NBadge: typeof import('naive-ui')['NBadge']
NButton: typeof import('naive-ui')['NButton']
NButtonGroup: typeof import('naive-ui')['NButtonGroup']
+ NCard: typeof import('naive-ui')['NCard']
NCarousel: typeof import('naive-ui')['NCarousel']
NCarouselItem: typeof import('naive-ui')['NCarouselItem']
NCheckbox: typeof import('naive-ui')['NCheckbox']
diff --git a/src/renderer/router/other.ts b/src/renderer/router/other.ts
index 81084e3..9b6487c 100644
--- a/src/renderer/router/other.ts
+++ b/src/renderer/router/other.ts
@@ -76,6 +76,16 @@ const otherRouter = [
back: true
},
component: () => import('@/views/music/MusicListPage.vue')
- }
+ },
+ {
+ path: '/playlist/import',
+ name: 'playlistImport',
+ meta: {
+ title: '歌单导入',
+ keepAlive: true,
+ back: true
+ },
+ component: () => import('@/views/playlist/ImportPlaylist.vue')
+ },
];
export default otherRouter;
diff --git a/src/renderer/views/playlist/ImportPlaylist.vue b/src/renderer/views/playlist/ImportPlaylist.vue
new file mode 100644
index 0000000..14aca92
--- /dev/null
+++ b/src/renderer/views/playlist/ImportPlaylist.vue
@@ -0,0 +1,627 @@
+
+ {{ t('comp.playlist.import.linkTips') }} {{ t('comp.playlist.import.textTips') }} {{ t('comp.playlist.import.textFormat') }} {{ t('comp.playlist.import.localTips') }}{{ t('comp.playlist.import.title') }}
+
+
+ {{ t('comp.playlist.import.importStatus') }}
+