import { relationalStore } from '@kit.ArkData'; import { Context } from '@kit.AbilityKit'; import Logger from './Logger'; import RdbUtils from './RdbUtils'; import { Playlist, PlaylistSong } from '../../viewmodel/Playlist'; import { PlaylistBackupData, PlaylistBackupItem, PlaylistSongBackupItem, ImportResult, ConflictResolution, BACKUP_FORMAT_VERSION } from '../../viewmodel/PlaylistBackup'; import { AppUtil } from '@pura/harmony-utils'; /** * 歌单数据库操作类 */ export default class PlaylistTable { private context: Context; private rdbStore: relationalStore.RdbStore | null = null; private initPromise: Promise; constructor(context: Context) { this.context = context; this.initPromise = this.initRdbStore(); } /** * 确保数据库已初始化 */ private async ensureInitialized(): Promise { await this.initPromise; } /** * 初始化数据库 */ private async initRdbStore(): Promise { try { const config: relationalStore.StoreConfig = { name: 'PlaylistStore.db', securityLevel: relationalStore.SecurityLevel.S1 // 使用标准安全级别 }; this.rdbStore = await relationalStore.getRdbStore(this.context, config); // 创建表 await this.createTables(); Logger.info('heanup PlaylistTable', '数据库初始化成功'); } catch (error) { Logger.error('heanup PlaylistTable', `初始化数据库失败: ${error.message}`); } } /** * 创建表 */ private async createTables(): Promise { if (!this.rdbStore) { return; } try { // 创建歌单表 await this.rdbStore.executeSql(RdbUtils.PLAYLIST_TABLE.sqlCreate); // 创建歌单歌曲关联表 await this.rdbStore.executeSql(RdbUtils.PLAYLIST_SONG_TABLE.sqlCreate); Logger.info('heanup PlaylistTable', '数据库表创建成功'); } catch (error) { Logger.error('heanup PlaylistTable', `创建表失败: ${error.message}`); } } /** * 生成唯一ID */ private generateId(): string { return Date.now().toString() + Math.random().toString(36).substr(2, 9); } /** * 创建歌单 */ async createPlaylist(name: string, description?: string, coverPath?: string): Promise { await this.ensureInitialized(); if (!this.rdbStore) { Logger.error('heanup PlaylistTable', '数据库未初始化'); return false; } try { const id = this.generateId(); const now = new Date().toISOString(); const sql = 'INSERT INTO playlistTable (id, name, coverPath, description, createTime, updateTime, songCount, sortOrder) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'; const params = [id, name, coverPath || null, description || null, now, now, 0, 0]; await this.rdbStore.executeSql(sql, params); Logger.info('heanup PlaylistTable', `歌单创建成功: ${name}`); this.triggerAutoBackup(); return true; } catch (error) { Logger.error('heanup PlaylistTable', `创建歌单失败: ${error.message}`); return false; } } /** * 删除歌单及其所有歌曲 */ async deletePlaylist(playlistId: string): Promise { if (!this.rdbStore) { return false; } try { // 先删除歌单歌曲关联 const deleteSongsSql = 'DELETE FROM playlistSongTable WHERE playlistId = ?'; await this.rdbStore.executeSql(deleteSongsSql, [playlistId]); // 再删除歌单 const deletePlaylistSql = 'DELETE FROM playlistTable WHERE id = ?'; await this.rdbStore.executeSql(deletePlaylistSql, [playlistId]); Logger.info('heanup PlaylistTable', `歌单删除成功: ${playlistId}`); this.triggerAutoBackup(); return true; } catch (error) { Logger.error('heanup PlaylistTable', `删除歌单失败: ${error.message}`); return false; } } /** * 更新歌单信息 */ async updatePlaylist(playlistId: string, name?: string, description?: string, coverPath?: string): Promise { if (!this.rdbStore) { return false; } try { const updateTime = new Date().toISOString(); const updates: string[] = []; const params: (string | number | null)[] = []; if (name !== undefined) { updates.push('name = ?'); params.push(name); } if (description !== undefined) { updates.push('description = ?'); params.push(description); } if (coverPath !== undefined) { updates.push('coverPath = ?'); params.push(coverPath); } updates.push('updateTime = ?'); params.push(updateTime); params.push(playlistId); const sql = `UPDATE playlistTable SET ${updates.join(', ')} WHERE id = ?`; await this.rdbStore.executeSql(sql, params); Logger.info('heanup PlaylistTable', `歌单更新成功: ${playlistId}`); this.triggerAutoBackup(); return true; } catch (error) { Logger.error('heanup PlaylistTable', `更新歌单失败: ${error.message}`); return false; } } /** * 查询所有歌单 */ async queryAllPlaylists(): Promise { await this.ensureInitialized(); if (!this.rdbStore) { Logger.error('heanup PlaylistTable', '数据库未初始化'); return []; } try { const sql = 'SELECT * FROM playlistTable ORDER BY sortOrder ASC, createTime DESC'; Logger.info('heanup PlaylistTable', '开始查询所有歌单'); const resultSet = await this.rdbStore.querySql(sql); const playlists: Playlist[] = []; if (resultSet.goToFirstRow()) { do { const playlistId = resultSet.getString(resultSet.getColumnIndex('id')); const playlistName = resultSet.getString(resultSet.getColumnIndex('name')); const songCount = resultSet.getLong(resultSet.getColumnIndex('songCount')); Logger.info('heanup PlaylistTable', `queryAllPlaylists: 从数据库读取 - ID: ${playlistId}, 名称: ${playlistName}, 歌曲数: ${songCount}`); const playlist = new Playlist( playlistId, playlistName, resultSet.getString(resultSet.getColumnIndex('createTime')), resultSet.getString(resultSet.getColumnIndex('updateTime')), songCount, resultSet.getLong(resultSet.getColumnIndex('sortOrder')), resultSet.getString(resultSet.getColumnIndex('coverPath')), resultSet.getString(resultSet.getColumnIndex('description')) ); playlists.push(playlist); } while (resultSet.goToNextRow()); } resultSet.close(); Logger.info('heanup PlaylistTable', `查询到 ${playlists.length} 个歌单`); return playlists; } catch (error) { Logger.error('heanup PlaylistTable', `查询歌单失败: ${error.message}`); return []; } } /** * 根据名称查询最近更新的歌单 */ async queryPlaylistByName(name: string): Promise { await this.ensureInitialized(); if (!this.rdbStore) { Logger.error('heanup PlaylistTable', '数据库未初始化'); return null; } try { const sql = 'SELECT * FROM playlistTable WHERE name = ? ORDER BY updateTime DESC LIMIT 1'; const resultSet = await this.rdbStore.querySql(sql, [name]); if (resultSet.goToFirstRow()) { const playlist = new Playlist( resultSet.getString(resultSet.getColumnIndex('id')), resultSet.getString(resultSet.getColumnIndex('name')), resultSet.getString(resultSet.getColumnIndex('createTime')), resultSet.getString(resultSet.getColumnIndex('updateTime')), resultSet.getLong(resultSet.getColumnIndex('songCount')), resultSet.getLong(resultSet.getColumnIndex('sortOrder')), resultSet.getString(resultSet.getColumnIndex('coverPath')), resultSet.getString(resultSet.getColumnIndex('description')) ); resultSet.close(); return playlist; } resultSet.close(); return null; } catch (error) { Logger.error('heanup PlaylistTable', `queryPlaylistByName失败: ${error.message}`); return null; } } /** * 根据ID查询歌单 */ async queryPlaylistById(playlistId: string): Promise { if (!this.rdbStore) { return null; } try { const sql = 'SELECT * FROM playlistTable WHERE id = ?'; const resultSet = await this.rdbStore.querySql(sql, [playlistId]); if (resultSet.goToFirstRow()) { const playlist = new Playlist( resultSet.getString(resultSet.getColumnIndex('id')), resultSet.getString(resultSet.getColumnIndex('name')), resultSet.getString(resultSet.getColumnIndex('createTime')), resultSet.getString(resultSet.getColumnIndex('updateTime')), resultSet.getLong(resultSet.getColumnIndex('songCount')), resultSet.getLong(resultSet.getColumnIndex('sortOrder')), resultSet.getString(resultSet.getColumnIndex('coverPath')), resultSet.getString(resultSet.getColumnIndex('description')) ); resultSet.close(); return playlist; } resultSet.close(); return null; } catch (error) { Logger.error('heanup PlaylistTable', `查询歌单失败: ${error.message}`); return null; } } /** * 添加歌曲到歌单 */ async addSongToPlaylist(playlistId: string, songFilePath: string): Promise { await this.ensureInitialized(); if (!this.rdbStore) { Logger.error('heanup PlaylistTable', '数据库未初始化'); return false; } try { Logger.info('heanup PlaylistTable', `开始添加歌曲到歌单: playlistId=${playlistId}, songFilePath=${songFilePath}`); // 检查歌曲是否已在歌单中 const isInPlaylist = await this.isSongInPlaylist(playlistId, songFilePath); if (isInPlaylist) { Logger.info('heanup PlaylistTable', '歌曲已在歌单中'); return false; } const id = this.generateId(); const addTime = new Date().toISOString(); const sql = 'INSERT INTO playlistSongTable (id, playlistId, songFilePath, addTime, sortOrder) VALUES (?, ?, ?, ?, ?)'; const params = [id, playlistId, songFilePath, addTime, 0]; Logger.info('heanup PlaylistTable', `执行SQL插入: ${sql}`); await this.rdbStore.executeSql(sql, params); Logger.info('heanup PlaylistTable', '歌曲插入成功'); // 更新歌单歌曲数量 Logger.info('heanup PlaylistTable', '开始更新歌单歌曲数量'); await this.updatePlaylistSongCount(playlistId); Logger.info('heanup PlaylistTable', `歌曲添加到歌单成功: ${songFilePath}`); this.triggerAutoBackup(); return true; } catch (error) { Logger.error('heanup PlaylistTable', `添加歌曲到歌单失败: ${error.message}`); return false; } } /** * 批量添加歌曲到歌单 */ async addSongsToPlaylist(playlistId: string, songFilePaths: string[]): Promise { await this.ensureInitialized(); if (!this.rdbStore) { Logger.error('heanup PlaylistTable', '数据库未初始化'); return false; } if (!songFilePaths || songFilePaths.length === 0) { Logger.error('heanup PlaylistTable', '歌曲路径列表为空'); return false; } try { Logger.info('heanup PlaylistTable', `开始批量添加歌曲到歌单: playlistId=${playlistId}, 歌曲数量=${songFilePaths.length}`); let successCount = 0; for (const songFilePath of songFilePaths) { try { // 检查歌曲是否已在歌单中 const isInPlaylist = await this.isSongInPlaylist(playlistId, songFilePath); if (isInPlaylist) { Logger.info('heanup PlaylistTable', `歌曲已在歌单中,跳过: ${songFilePath}`); continue; } const id = this.generateId(); const addTime = new Date().toISOString(); const sql = 'INSERT INTO playlistSongTable (id, playlistId, songFilePath, addTime, sortOrder) VALUES (?, ?, ?, ?, ?)'; const params = [id, playlistId, songFilePath, addTime, 0]; await this.rdbStore.executeSql(sql, params); successCount++; Logger.info('heanup PlaylistTable', `成功添加歌曲: ${songFilePath}`); } catch (error) { Logger.error('heanup PlaylistTable', `添加歌曲失败: ${songFilePath}, 错误: ${error.message}`); } } // 更新歌单歌曲数量 Logger.info('heanup PlaylistTable', '开始更新歌单歌曲数量'); await this.updatePlaylistSongCount(playlistId); Logger.info('heanup PlaylistTable', `批量添加歌曲完成,成功添加 ${successCount} 首,共 ${songFilePaths.length} 首`); return successCount > 0; } catch (error) { Logger.error('heanup PlaylistTable', `批量添加歌曲到歌单失败: ${error.message}`); return false; } } /** * 从歌单中移除歌曲 */ async removeSongFromPlaylist(playlistId: string, songFilePath: string): Promise { if (!this.rdbStore) { Logger.error('heanup PlaylistTable', 'removeSongFromPlaylist: 数据库未初始化'); return false; } try { Logger.info('heanup PlaylistTable', `removeSongFromPlaylist: 开始删除歌曲 ${songFilePath} 从歌单 ${playlistId}`); const sql = 'DELETE FROM playlistSongTable WHERE playlistId = ? AND songFilePath = ?'; await this.rdbStore.executeSql(sql, [playlistId, songFilePath]); Logger.info('heanup PlaylistTable', `removeSongFromPlaylist: 数据库删除操作完成`); // 更新歌单歌曲数量 Logger.info('heanup PlaylistTable', `removeSongFromPlaylist: 开始更新歌单数量`); await this.updatePlaylistSongCount(playlistId); Logger.info('heanup PlaylistTable', `removeSongFromPlaylist: 歌曲从歌单移除成功: ${songFilePath}`); this.triggerAutoBackup(); return true; } catch (error) { Logger.error('heanup PlaylistTable', `removeSongFromPlaylist: 从歌单移除歌曲失败: ${error.message}`); return false; } } /** * 从所有歌单中移除指定歌曲(当歌曲文件被删除时调用) */ async removeSongFromAllPlaylists(songFilePath: string): Promise { if (!this.rdbStore) { Logger.error('heanup PlaylistTable', 'removeSongFromAllPlaylists: 数据库未初始化'); return []; } try { Logger.info('heanup PlaylistTable', `removeSongFromAllPlaylists: 开始处理歌曲 ${songFilePath}`); // 1. 先查询这首歌在哪些歌单中 const sql = 'SELECT DISTINCT playlistId FROM playlistSongTable WHERE songFilePath = ?'; const resultSet = await this.rdbStore.querySql(sql, [songFilePath]); const affectedPlaylistIds: string[] = []; if (resultSet.goToFirstRow()) { do { const playlistId = resultSet.getString(0); affectedPlaylistIds.push(playlistId); Logger.info('heanup PlaylistTable', `removeSongFromAllPlaylists: 找到歌单 ${playlistId}`); } while (resultSet.goToNextRow()); } resultSet.close(); if (affectedPlaylistIds.length === 0) { Logger.info('heanup PlaylistTable', `removeSongFromAllPlaylists: 歌曲不在任何歌单中: ${songFilePath}`); return []; } Logger.info('heanup PlaylistTable', `removeSongFromAllPlaylists: 歌曲在 ${affectedPlaylistIds.length} 个歌单中`); // 2. 从所有歌单中删除这首歌 const deleteSql = 'DELETE FROM playlistSongTable WHERE songFilePath = ?'; await this.rdbStore.executeSql(deleteSql, [songFilePath]); Logger.info('heanup PlaylistTable', `removeSongFromAllPlaylists: 已从数据库删除歌曲记录`); // 3. 更新所有受影响歌单的歌曲数量 for (const playlistId of affectedPlaylistIds) { Logger.info('heanup PlaylistTable', `removeSongFromAllPlaylists: 开始更新歌单 ${playlistId} 的数量`); await this.updatePlaylistSongCount(playlistId); } Logger.info('heanup PlaylistTable', `removeSongFromAllPlaylists: 歌曲已从 ${affectedPlaylistIds.length} 个歌单中移除: ${songFilePath}`); return affectedPlaylistIds; } catch (error) { Logger.error('heanup PlaylistTable', `removeSongFromAllPlaylists: 从所有歌单移除歌曲失败: ${error.message}`); return []; } } /** * 查询歌单中的歌曲 */ async queryPlaylistSongs(playlistId: string): Promise { await this.ensureInitialized(); if (!this.rdbStore) { Logger.error('heanup PlaylistTable', '数据库未初始化'); return []; } try { const sql = 'SELECT * FROM playlistSongTable WHERE playlistId = ? ORDER BY sortOrder ASC, addTime ASC'; Logger.info('heanup PlaylistTable', `queryPlaylistSongs: 开始查询歌单歌曲, playlistId=${playlistId}`); Logger.info('heanup PlaylistTable', `queryPlaylistSongs: SQL=${sql}`); const resultSet = await this.rdbStore.querySql(sql, [playlistId]); Logger.info('heanup PlaylistTable', `queryPlaylistSongs: 查询执行完成, rowCount=${resultSet.rowCount}`); const songs: PlaylistSong[] = []; if (resultSet.goToFirstRow()) { Logger.info('heanup PlaylistTable', 'queryPlaylistSongs: 移动到第一行成功'); do { const song = new PlaylistSong( resultSet.getString(resultSet.getColumnIndex('id')), resultSet.getString(resultSet.getColumnIndex('playlistId')), resultSet.getString(resultSet.getColumnIndex('songFilePath')), resultSet.getString(resultSet.getColumnIndex('addTime')), resultSet.getLong(resultSet.getColumnIndex('sortOrder')) ); songs.push(song); Logger.info('heanup PlaylistTable', `queryPlaylistSongs: 添加歌曲, songFilePath=${song.songFilePath}`); } while (resultSet.goToNextRow()); } else { Logger.info('heanup PlaylistTable', 'queryPlaylistSongs: 没有数据,无法移动到第一行'); } resultSet.close(); Logger.info('heanup PlaylistTable', `queryPlaylistSongs: 查询到 ${songs.length} 首歌曲`); return songs; } catch (error) { Logger.error('heanup PlaylistTable', `queryPlaylistSongs: 查询歌单歌曲失败: ${error.message}`); Logger.error('heanup PlaylistTable', `queryPlaylistSongs: 错误堆栈: ${error.stack || '无堆栈信息'}`); return []; } } /** * 检查歌曲是否在歌单中 */ async isSongInPlaylist(playlistId: string, songFilePath: string): Promise { if (!this.rdbStore) { return false; } try { const sql = 'SELECT COUNT(*) as count FROM playlistSongTable WHERE playlistId = ? AND songFilePath = ?'; const resultSet = await this.rdbStore.querySql(sql, [playlistId, songFilePath]); let isInPlaylist = false; if (resultSet.goToFirstRow()) { const count = resultSet.getLong(resultSet.getColumnIndex('count')); isInPlaylist = count > 0; } resultSet.close(); return isInPlaylist; } catch (error) { Logger.error('heanup PlaylistTable', `检查歌曲是否在歌单中失败: ${error.message}`); return false; } } /** * 更新歌单歌曲数量 */ private async updatePlaylistSongCount(playlistId: string): Promise { if (!this.rdbStore) { Logger.error('heanup PlaylistTable', 'updatePlaylistSongCount: 数据库未初始化'); return; } try { Logger.info('heanup PlaylistTable', `updatePlaylistSongCount: 开始更新歌单 ${playlistId} 的歌曲数量`); const countSql = 'SELECT COUNT(*) as count FROM playlistSongTable WHERE playlistId = ?'; const resultSet = await this.rdbStore.querySql(countSql, [playlistId]); let count = 0; if (resultSet.goToFirstRow()) { count = resultSet.getLong(resultSet.getColumnIndex('count')); } resultSet.close(); Logger.info('heanup PlaylistTable', `updatePlaylistSongCount: 统计到 ${count} 首歌曲`); const updateSql = 'UPDATE playlistTable SET songCount = ?, updateTime = ? WHERE id = ?'; const updateTime = new Date().toISOString(); await this.rdbStore.executeSql(updateSql, [count, updateTime, playlistId]); Logger.info('heanup PlaylistTable', `updatePlaylistSongCount: 数据库更新成功,songCount = ${count}`); } catch (error) { Logger.error('heanup PlaylistTable', `updatePlaylistSongCount: 更新歌单歌曲数量失败: ${error.message}`); } } /** * 强制同步歌单歌曲数量(公开方法,用于修复数据不一致) */ async syncPlaylistSongCount(playlistId: string): Promise { await this.ensureInitialized(); await this.updatePlaylistSongCount(playlistId); Logger.info('heanup PlaylistTable', `已强制同步歌单 ${playlistId} 的歌曲数量`); } /** * 清理歌单中无效的歌曲记录(歌曲文件已不存在) */ async removeInvalidSongFromPlaylist(playlistId: string, songFilePath: string): Promise { if (!this.rdbStore) { Logger.error('heanup PlaylistTable', 'removeInvalidSongFromPlaylist: 数据库未初始化'); return false; } try { Logger.info('heanup PlaylistTable', `removeInvalidSongFromPlaylist: 开始清理无效歌曲 ${songFilePath} 从歌单 ${playlistId}`); const sql = 'DELETE FROM playlistSongTable WHERE playlistId = ? AND songFilePath = ?'; await this.rdbStore.executeSql(sql, [playlistId, songFilePath]); Logger.info('heanup PlaylistTable', `removeInvalidSongFromPlaylist: 数据库删除操作完成`); // 更新歌单歌曲数量 Logger.info('heanup PlaylistTable', `removeInvalidSongFromPlaylist: 开始更新歌单数量`); await this.updatePlaylistSongCount(playlistId); Logger.info('heanup PlaylistTable', `removeInvalidSongFromPlaylist: 无效歌曲从歌单清理成功: ${songFilePath}`); return true; } catch (error) { Logger.error('heanup PlaylistTable', `removeInvalidSongFromPlaylist: 清理无效歌曲失败: ${error.message}`); return false; } } /** * 更新歌单排序 */ async updatePlaylistSortOrder(playlistId: string, sortOrder: number): Promise { if (!this.rdbStore) { return false; } try { const updateTime = new Date().toISOString(); const sql = 'UPDATE playlistTable SET sortOrder = ?, updateTime = ? WHERE id = ?'; await this.rdbStore.executeSql(sql, [sortOrder, updateTime, playlistId]); Logger.info('heanup PlaylistTable', `歌单排序更新成功: ${playlistId}`); return true; } catch (error) { Logger.error('heanup PlaylistTable', `更新歌单排序失败: ${error.message}`); return false; } } /** * 更新歌单歌曲排序 */ async updatePlaylistSongSortOrder(playlistId: string, songFilePath: string, sortOrder: number): Promise { if (!this.rdbStore) { Logger.info('heanup PlaylistTable', `rdbStore未初始化: ${songFilePath}`); return false; } try { const sql = 'UPDATE playlistSongTable SET sortOrder = ? WHERE playlistId = ? AND songFilePath = ?'; await this.rdbStore.executeSql(sql, [sortOrder, playlistId, songFilePath]); Logger.info('heanup PlaylistTable', `歌单歌曲排序更新成功: ${songFilePath}`); return true; } catch (error) { Logger.error('heanup PlaylistTable', `更新歌单歌曲排序失败: ${error.message}`); return false; } } /** * 导出所有歌单及其歌曲为备份数据 */ async exportAllPlaylists(): Promise { await this.ensureInitialized(); const backupData: PlaylistBackupData = { version: BACKUP_FORMAT_VERSION, exportTime: new Date().toISOString(), appVersion: AppUtil.getVersionName(), playlists: [] }; if (!this.rdbStore) { Logger.error('heanup PlaylistTable', 'exportAllPlaylists: 数据库未初始化'); return backupData; } try { const playlists = await this.queryAllPlaylists(); Logger.info('heanup PlaylistTable', `exportAllPlaylists: 开始导出 ${playlists.length} 个歌单`); for (let i = 0; i < playlists.length; i++) { const playlist = playlists[i]; const songs = await this.queryPlaylistSongs(playlist.id); const songBackups: PlaylistSongBackupItem[] = []; for (let j = 0; j < songs.length; j++) { const song = songs[j]; songBackups.push({ songFilePath: song.songFilePath, addTime: song.addTime, sortOrder: song.sortOrder }); } const playlistBackup: PlaylistBackupItem = { id: playlist.id, name: playlist.name, coverPath: playlist.coverPath || '', description: playlist.description || '', createTime: playlist.createTime, updateTime: playlist.updateTime, songCount: playlist.songCount, sortOrder: playlist.sortOrder, songs: songBackups }; backupData.playlists.push(playlistBackup); } Logger.info('heanup PlaylistTable', `exportAllPlaylists: 导出完成, ${backupData.playlists.length} 个歌单`); return backupData; } catch (error) { Logger.error('heanup PlaylistTable', `exportAllPlaylists: 导出失败: ${(error as Error).message}`); return backupData; } } /** * 从备份数据导入歌单 * @param backupData 备份数据 * @param conflictStrategy 冲突解决策略(null 表示需要逐一询问,由调用方处理) * @param conflictsToSkip 需要跳过的歌单名称集合 * @param conflictsToOverwrite 需要覆盖的歌单名称集合 * @param conflictsToRename 需要重命名的歌单名称集合 */ async importPlaylists( backupData: PlaylistBackupData, conflictsToSkip: Set, conflictsToOverwrite: Set, conflictsToRename: Set ): Promise { await this.ensureInitialized(); const result: ImportResult = { totalPlaylists: backupData.playlists.length, importedPlaylists: 0, skippedPlaylists: 0, overwrittenPlaylists: 0, renamedPlaylists: 0, totalSongs: 0, importedSongs: 0, importedAccounts: 0, skippedAccounts: 0, settingsImported: false }; if (!this.rdbStore) { Logger.error('heanup PlaylistTable', 'importPlaylists: 数据库未初始化'); return result; } try { for (let i = 0; i < backupData.playlists.length; i++) { const playlistItem = backupData.playlists[i]; result.totalSongs += playlistItem.songs.length; const existingPlaylist = await this.queryPlaylistByName(playlistItem.name); if (existingPlaylist) { // 存在同名歌单,按策略处理 if (conflictsToSkip.has(playlistItem.name)) { result.skippedPlaylists++; Logger.info('heanup PlaylistTable', `importPlaylists: 跳过歌单: ${playlistItem.name}`); continue; } else if (conflictsToOverwrite.has(playlistItem.name)) { // 覆盖:先删除旧歌单 await this.deletePlaylist(existingPlaylist.id); result.overwrittenPlaylists++; Logger.info('heanup PlaylistTable', `importPlaylists: 覆盖歌单: ${playlistItem.name}`); } else if (conflictsToRename.has(playlistItem.name)) { // 重命名 const newName = await this.generateUniqueName(playlistItem.name); playlistItem.name = newName; result.renamedPlaylists++; Logger.info('heanup PlaylistTable', `importPlaylists: 重命名歌单为: ${newName}`); } else { // 默认跳过 result.skippedPlaylists++; continue; } } // 创建歌单 const created = await this.createPlaylist( playlistItem.name, playlistItem.description, playlistItem.coverPath ); if (!created) { Logger.error('heanup PlaylistTable', `importPlaylists: 创建歌单失败: ${playlistItem.name}`); continue; } // 查询刚创建的歌单 const newPlaylist = await this.queryPlaylistByName(playlistItem.name); if (!newPlaylist) { Logger.error('heanup PlaylistTable', `importPlaylists: 找不到新建歌单: ${playlistItem.name}`); continue; } result.importedPlaylists++; // 导入歌曲关联 const songPaths: string[] = []; for (let j = 0; j < playlistItem.songs.length; j++) { songPaths.push(playlistItem.songs[j].songFilePath); } if (songPaths.length > 0) { const addResult = await this.addSongsToPlaylist(newPlaylist.id, songPaths); if (addResult) { result.importedSongs += songPaths.length; } } Logger.info('heanup PlaylistTable', `importPlaylists: 导入歌单成功: ${playlistItem.name}, ${songPaths.length} 首歌曲`); } Logger.info('heanup PlaylistTable', `importPlaylists: 导入完成, 共 ${result.importedPlaylists} 个歌单, ${result.importedSongs} 首歌曲`); return result; } catch (error) { Logger.error('heanup PlaylistTable', `importPlaylists: 导入失败: ${(error as Error).message}`); return result; } } /** * 生成不重复的歌单名称 */ private async generateUniqueName(baseName: string): Promise { let suffix = 2; let candidateName = `${baseName} (${suffix})`; while (true) { const existing = await this.queryPlaylistByName(candidateName); if (!existing) { return candidateName; } suffix++; candidateName = `${baseName} (${suffix})`; } } /** * 检测备份数据中与现有歌单的冲突 */ async detectConflicts(backupData: PlaylistBackupData): Promise { await this.ensureInitialized(); const conflicts: string[] = []; for (let i = 0; i < backupData.playlists.length; i++) { const playlistItem = backupData.playlists[i]; const existing = await this.queryPlaylistByName(playlistItem.name); if (existing) { conflicts.push(playlistItem.name); } } return conflicts; } /** * 自动备份回调(由 PlaylistBackupManager 注册,避免循环依赖) */ private static autoBackupCallback: (() => void) | null = null; static registerAutoBackupCallback(callback: () => void): void { PlaylistTable.autoBackupCallback = callback; } /** * 触发自动备份 */ private triggerAutoBackup(): void { if (PlaylistTable.autoBackupCallback) { PlaylistTable.autoBackupCallback(); } } }