import { common } from '@kit.AbilityKit'; import { CommonConstants } from '../common/constants/CommonConstants'; import { VideoItem } from '../viewmodel/VideoItem'; import { ArrayUtil, FileUtil, LogUtil, PreferencesUtil, StrUtil, ToastUtil } from '@pura/harmony-utils'; import MediaTable from '../common/util/MediaTable'; import PlaylistTable from '../common/util/PlaylistTable'; import { EventConstants } from '../common/constants/EventConstants'; import { emitter } from '@kit.BasicServicesKit'; import { taskpool } from '@kit.ArkTS'; // 批量删除 @Component export struct DeleteComptent { @State isDeleteYuan: boolean = true @State isDeletePicture: boolean = true @State isDeleteLrc: boolean = true onDeleteResult = (_result: boolean) => { } onCancel = () => { } @Prop selectedFiles: Array @StorageProp('themeColor') themeColor: string = CommonConstants.DEFAULT_THEME_COLOR; context = this.getUIContext().getHostContext() as common.UIAbilityContext async aboutToAppear() { this.isDeleteYuan = PreferencesUtil.getBooleanSync('isDeleteYuan', true); this.isDeletePicture = PreferencesUtil.getBooleanSync('isDeletePicture', true); this.isDeleteLrc = PreferencesUtil.getBooleanSync('isDeleteLrc', true) } build() { Column() { Text('温馨提醒').fontSize(20).margin({ top: 10, bottom: 10 }) Text('是否删除这些文件?').fontSize(16).margin({ top: 10, bottom: 10 }) Column() { // 删除源文件选项 Button({ type: ButtonType.Capsule, stateEffect: true }) { Row() { SymbolGlyph($r('sys.symbol.doc_text')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text("删除源文件") .fontSize(16) .layoutWeight(1) .margin({ left: 10 }) Toggle({ type: ToggleType.Checkbox, isOn: this.isDeleteYuan }) .onChange((isOn: boolean) => { this.isDeleteYuan = isOn; PreferencesUtil.put('isDeleteYuan', this.isDeleteYuan) }) .margin({ right: 28 }) .selectedColor(this.themeColor) } } .backgroundColor(Color.Transparent) .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 }) .onClick(() => { this.isDeleteYuan = !this.isDeleteYuan }) .width('100%') .padding(10) .margin({ left: 18 }) // 删除封面选项 Button({ type: ButtonType.Capsule, stateEffect: true }) { Row() { SymbolGlyph($r('sys.symbol.picture')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text("删除封面文件") .fontSize(16) .layoutWeight(1) .margin({ left: 10 }) Toggle({ type: ToggleType.Checkbox, isOn: this.isDeletePicture }) .onChange((isOn: boolean) => { this.isDeletePicture = isOn; PreferencesUtil.put('isDeletePicture', this.isDeletePicture) }) .margin({ right: 28 }) .selectedColor(this.themeColor) } } .backgroundColor(Color.Transparent) .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 }) .onClick(() => { this.isDeletePicture = !this.isDeletePicture }) .width('100%') .padding(10) .margin({ left: 18 }) // 删除歌词选项 Button({ type: ButtonType.Capsule, stateEffect: true }) { Row() { SymbolGlyph($r('sys.symbol.input_mode')) .fontSize(20) .fontColor([this.themeColor]) .alignSelf(ItemAlign.Center) .margin({ left: 15 }) Text("删除歌词文件") .fontSize(16) .layoutWeight(1) .margin({ left: 10 }) Toggle({ type: ToggleType.Checkbox, isOn: this.isDeleteLrc }) .onChange((isOn: boolean) => { this.isDeleteLrc = isOn; PreferencesUtil.put('isDeleteLrc', this.isDeleteLrc) }) .margin({ right: 28 }) .selectedColor(this.themeColor) } } .backgroundColor(Color.Transparent) .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 }) .onClick(() => { this.isDeleteLrc = !this.isDeleteLrc }) .width('100%') .padding(10) .margin({ left: 18, bottom: 10 }) } .visibility(this.selectedFiles.length==1&&this.selectedFiles[0].type==CommonConstants.TYPE_IS_DIR? Visibility.None:Visibility.Visible) Flex({ justifyContent: FlexAlign.SpaceAround }) { Button($r('app.string.cancel')) .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.8 }) .padding(15) .width(120) .onClick(() => { this.onCancel() }) .backgroundColor($r('app.color.silvery')) .backgroundBlurStyle(BlurStyle.COMPONENT_THICK) .fontColor(Color.Black) Button($r('app.string.sure')) .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.8 }) .padding(15) .width(120) .onClick(() => { this.doDeleteTask() }) .backgroundColor($r('app.color.silvery')) .backgroundBlurStyle(BlurStyle.COMPONENT_THICK) .fontColor(Color.Red) }.margin({ bottom: 10 }) } .backgroundColor($r('app.color.start_window_background')) .backgroundBlurStyle(BlurStyle.Regular) } doDeleteTask(){ const task = new taskpool.Task( deleteMultipleFiles, JSON.stringify(this.selectedFiles), this.isDeleteYuan,this.isDeletePicture,this.isDeleteLrc,this.context ); taskpool.execute(task, taskpool.Priority.HIGH).then((result) => { if(result){ this.onDeleteResult(true) }else { this.onDeleteResult(false) } }).catch((error: Error) => { console.error('Subtitle sync failed:', error); }); } } //多选删除文件 @Concurrent async function deleteMultipleFiles( selectedFilesStr:string, isDeleteYuan:boolean, isDeletePicture:boolean, isDeleteLrc:boolean, context:Context ) { const selectedFiles: VideoItem[] = JSON.parse(selectedFilesStr) if (ArrayUtil.isNotEmpty(selectedFiles)) { const table: MediaTable = new MediaTable(context) const playlistTable: PlaylistTable = new PlaylistTable(context) // 初始化数据库 await new Promise((resolve, reject) => { table.getRdbStore(context, (err:Error) => { err ? reject(err) : resolve(); }); }); let hasPlaylistChanges = false; // 标记是否有歌单变化 for (const item of selectedFiles) { console.info('onecold delete filePath = ' + item.filePath); if (item.type === CommonConstants.TYPE_IS_DIR) { table.deleteDataForParentPath(item.filePath, () => { FileUtil.rmdir(item.filePath).then(() => { return true }).catch((error: Error) => { console.error(error.message); return false }); }); } else { table.deleteData(item, async () => { if(isDeleteYuan){ await FileUtil.unlink(item.filePath) } console.info(`onecold 封面文件=: ${item.pixelMapPath}`); if (isDeletePicture && item.pixelMapPath) { const picPath = FileUtil.getFilePath(item.pixelMapPath)//获取图 if (FileUtil.accessSync(picPath)) { await FileUtil.unlink(picPath); console.info(`onecold 封面文件已删除: ${picPath}`); } } const lyricPath = item.filePath?.replace(/\.[^/.]+$/, ".lrc"); console.info(`onecold 歌词文件=: ${lyricPath}`); if(isDeleteLrc) { if (lyricPath && FileUtil.accessSync(lyricPath)) { await FileUtil.unlink(lyricPath); console.info( `onecold 歌词文件已删除: ${lyricPath}`); } } // this.onDeleteResult(true,item) }); // 先从所有歌单中移除这首歌(如果存在的话) LogUtil.info('heanup DeleteComptent', `准备从歌单中移除歌曲: ${item.name}, filePath: ${item.filePath}`); if (item.filePath) { try { const affectedPlaylists = await playlistTable.removeSongFromAllPlaylists(item.filePath); LogUtil.info('heanup DeleteComptent', `removeSongFromAllPlaylists 返回了 ${affectedPlaylists.length} 个受影响的歌单`); if (affectedPlaylists.length > 0) { hasPlaylistChanges = true; LogUtil.info('heanup DeleteComptent', `歌曲已从 ${affectedPlaylists.length} 个歌单中移除: ${item.name}`); } else { LogUtil.info('heanup DeleteComptent', `歌曲不在任何歌单中: ${item.name}`); } } catch (error) { LogUtil.error('heanup DeleteComptent', `从歌单移除歌曲失败: ${(error as Error).message}`); } } else { LogUtil.warn('heanup DeleteComptent', `歌曲 ${item.name} 的 filePath 为空`); } } } // 如果有歌单变化,发送刷新事件 if (hasPlaylistChanges) { const eventRefresh: emitter.InnerEvent = { eventId: EventConstants.EVENT_PLAYLIST_REFRESH }; emitter.emit(eventRefresh, {}); LogUtil.info('heanup DeleteComptent', '已发送歌单刷新事件,更新歌单数量'); } } return true }