|
@@ -28,6 +28,8 @@ export struct ScanFilePage{
|
|
|
// 新增状态变量
|
|
// 新增状态变量
|
|
|
@State currentInsertCount: number = 0 // 当前已扫描并插入的歌曲数量
|
|
@State currentInsertCount: number = 0 // 当前已扫描并插入的歌曲数量
|
|
|
@State currentFilePath: string = '' // 当前正在处理的文件路径
|
|
@State currentFilePath: string = '' // 当前正在处理的文件路径
|
|
|
|
|
+ @State invalidMusicCount: number = 0 // 无效音乐文件数量
|
|
|
|
|
+ @State isCorrecting: boolean = false // 是否正在校正数据
|
|
|
|
|
|
|
|
context = this.getUIContext().getHostContext() as common.UIAbilityContext
|
|
context = this.getUIContext().getHostContext() as common.UIAbilityContext
|
|
|
// @StorageProp('mediaKuList') mediaKuList: Array<VideoItem> = []; //媒体库文件
|
|
// @StorageProp('mediaKuList') mediaKuList: Array<VideoItem> = []; //媒体库文件
|
|
@@ -99,6 +101,12 @@ export struct ScanFilePage{
|
|
|
lottie.pause()
|
|
lottie.pause()
|
|
|
},88)
|
|
},88)
|
|
|
|
|
|
|
|
|
|
+ setTimeout(()=>{
|
|
|
|
|
+ // 显示校正数据对话框
|
|
|
|
|
+ this.showCorrectDataDialog(false)
|
|
|
|
|
+ },50000)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
onColorModeChange() {
|
|
onColorModeChange() {
|
|
|
this.isDarkMode = this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK
|
|
this.isDarkMode = this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK
|
|
@@ -209,7 +217,19 @@ export struct ScanFilePage{
|
|
|
.layoutWeight(1)
|
|
.layoutWeight(1)
|
|
|
.clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
|
|
.clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
+ Button({ type: ButtonType.Circle, stateEffect: true }) {
|
|
|
|
|
+ SymbolGlyph($r('sys.symbol.exclamationmark_circle'))
|
|
|
|
|
+ .attributeModifier(new SymbolGlyphFancyModifier(25, '', ''))
|
|
|
|
|
+ }
|
|
|
|
|
+ .attributeModifier(new ButtonFancyModifier(40, 40))
|
|
|
|
|
+ .animation({ duration: 300, curve: Curve.Ease })
|
|
|
|
|
+ .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
|
|
|
|
|
+ .attributeModifier(new ShadowModifier())
|
|
|
|
|
+ .zIndex(0)
|
|
|
|
|
+ .onClick(() => {
|
|
|
|
|
+ // 显示校正数据对话框
|
|
|
|
|
+ this.showCorrectDataDialog(true)
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
.padding({ top: this.topSafeHeight+10, left: 10, right: 10,bottom:12 })
|
|
.padding({ top: this.topSafeHeight+10, left: 10, right: 10,bottom:12 })
|
|
@@ -444,6 +464,141 @@ export struct ScanFilePage{
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 显示校正数据对话框
|
|
|
|
|
+ */
|
|
|
|
|
+ showCorrectDataDialog(isEmptyShowDialog:boolean) {
|
|
|
|
|
+ // 先查询无效音乐数量
|
|
|
|
|
+ this.checkInvalidMusicCount(isEmptyShowDialog)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查无效音乐数量并显示对话框
|
|
|
|
|
+ */
|
|
|
|
|
+ async checkInvalidMusicCount(isEmptyShowDialog:boolean) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const table: MediaTable = new MediaTable(this.context);
|
|
|
|
|
+ console.info('heanup ScanFilePage', `checkInvalidMusicCount`)
|
|
|
|
|
+ await new Promise<void>((resolve, reject) => {
|
|
|
|
|
+ table.getRdbStore(this.context, (err:Error) => {
|
|
|
|
|
+ err ? reject(err) : resolve();
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ const allMusic = await this.queryAllLocalMusic(table);
|
|
|
|
|
+ console.info('heanup ScanFilePage', `查询到的所有音乐数量: ${allMusic.length}`)
|
|
|
|
|
+ let invalidCount = 0;
|
|
|
|
|
+ const invalidFilePaths: string[] = [];
|
|
|
|
|
+
|
|
|
|
|
+ for (const item of allMusic) {
|
|
|
|
|
+ // 检查是否是本地音乐(filePath包含包名)
|
|
|
|
|
+ if (item.filePath&&item.type===CommonConstants.TYPE_LOCAL && item.filePath.includes(this.packName)) {
|
|
|
|
|
+ const exists = await FileUtil.accessSync(item.filePath);
|
|
|
|
|
+ if (!exists) {
|
|
|
|
|
+ invalidCount++;
|
|
|
|
|
+ invalidFilePaths.push(item.filePath);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.invalidMusicCount = invalidCount;
|
|
|
|
|
+ console.info('heanup ScanFilePage', `showCustomContentDialog`)
|
|
|
|
|
+ // 显示校正对话框
|
|
|
|
|
+ if(this.invalidMusicCount>0||isEmptyShowDialog){
|
|
|
|
|
+ DialogHelper.showCustomContentDialog({
|
|
|
|
|
+ dialogId: 'correctData',
|
|
|
|
|
+ title: "校正数据",
|
|
|
|
|
+ autoCancel: true,
|
|
|
|
|
+ backCancel: true,
|
|
|
|
|
+ contentBuilder: () => {
|
|
|
|
|
+ this.correctDataContentBuilder(invalidCount);
|
|
|
|
|
+ },
|
|
|
|
|
+ buttons: [],
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ Logger.error('heanup ScanFilePage', `检查无效音乐失败: ${JSON.stringify(error)}`);
|
|
|
|
|
+ ToastUtil.showToast('检查失败,请稍后重试');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 查询所有本地音乐
|
|
|
|
|
+ */
|
|
|
|
|
+ async queryAllLocalMusic(table: MediaTable): Promise<VideoItem[]> {
|
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
|
+ table.query(0, (result: VideoItem[]) => {
|
|
|
|
|
+ resolve(result);
|
|
|
|
|
+ }, true);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 执行校正数据
|
|
|
|
|
+ */
|
|
|
|
|
+ async doCorrectData() {
|
|
|
|
|
+ if (this.isCorrecting) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.isCorrecting = true;
|
|
|
|
|
+ DialogHelper.closeDialog('correctData');
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const table: MediaTable = new MediaTable(this.context);
|
|
|
|
|
+ await new Promise<void>((resolve, reject) => {
|
|
|
|
|
+ table.getRdbStore(this.context, (err:Error) => {
|
|
|
|
|
+ err ? reject(err) : resolve();
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ const allMusic = await this.queryAllLocalMusic(table);
|
|
|
|
|
+
|
|
|
|
|
+ let deletedCount = 0;
|
|
|
|
|
+ this.currentFilePath = '正在校正数据...';
|
|
|
|
|
+ this.textVisi = Visibility.Visible;
|
|
|
|
|
+
|
|
|
|
|
+ for (const item of allMusic) {
|
|
|
|
|
+ // 检查是否是本地音乐(filePath包含包名)
|
|
|
|
|
+ if (item.filePath && item.filePath.includes(this.packName)) {
|
|
|
|
|
+ const exists = await FileUtil.accessSync(item.filePath);
|
|
|
|
|
+ if (!exists) {
|
|
|
|
|
+ // 文件不存在,删除数据库记录
|
|
|
|
|
+ await new Promise<void>((resolve) => {
|
|
|
|
|
+ table.deleteDataFilePath(item.filePath, (success: boolean) => {
|
|
|
|
|
+ if (success) {
|
|
|
|
|
+ deletedCount++;
|
|
|
|
|
+ Logger.info('heanup ScanFilePage', `删除无效记录: ${item.filePath}`);
|
|
|
|
|
+ }
|
|
|
|
|
+ resolve();
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.currentFilePath = `校正完成!删除了 ${deletedCount} 条无效记录`;
|
|
|
|
|
+ this.currentInsertCount = deletedCount;
|
|
|
|
|
+
|
|
|
|
|
+ // 显示成功提示
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ ToastUtil.showToast(`校正完成,删除了 ${deletedCount} 条无效记录`);
|
|
|
|
|
+ }, 500);
|
|
|
|
|
+
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ Logger.error('heanup ScanFilePage', `校正数据失败: ${JSON.stringify(error)}`);
|
|
|
|
|
+ ToastUtil.showToast('校正失败,请稍后重试');
|
|
|
|
|
+ this.currentFilePath = '校正失败';
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ this.isCorrecting = false;
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ this.currentFilePath = '';
|
|
|
|
|
+ this.currentInsertCount = 0;
|
|
|
|
|
+ this.textVisi = Visibility.Hidden;
|
|
|
|
|
+ }, 3000);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@Builder
|
|
@Builder
|
|
|
customTipsBuilder(content: string) {
|
|
customTipsBuilder(content: string) {
|
|
|
Column() {
|
|
Column() {
|
|
@@ -486,6 +641,64 @@ export struct ScanFilePage{
|
|
|
.padding(10)
|
|
.padding(10)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Builder
|
|
|
|
|
+ correctDataContentBuilder(invalidCount: number) {
|
|
|
|
|
+ Column() {
|
|
|
|
|
+ if (invalidCount > 0) {
|
|
|
|
|
+ Text(`发现 ${invalidCount} 条无效的音乐记录`)
|
|
|
|
|
+ .fontColor($r('app.color.text_color'))
|
|
|
|
|
+ .fontSize(16)
|
|
|
|
|
+ .margin({ bottom: 10 })
|
|
|
|
|
+
|
|
|
|
|
+ Text('这些音乐文件已被删除或移动,是否要清理这些无效记录?')
|
|
|
|
|
+ .fontColor(Color.Gray)
|
|
|
|
|
+ .fontSize(14)
|
|
|
|
|
+ .margin({ bottom: 20 })
|
|
|
|
|
+
|
|
|
|
|
+ Row() {
|
|
|
|
|
+ Button('取消')
|
|
|
|
|
+ .fontColor(Color.White)
|
|
|
|
|
+ .backgroundColor(Color.Gray)
|
|
|
|
|
+ .height(50)
|
|
|
|
|
+ .layoutWeight(1)
|
|
|
|
|
+ .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.7})
|
|
|
|
|
+ .margin({ right: 10 })
|
|
|
|
|
+ .onClick(() => {
|
|
|
|
|
+ DialogHelper.closeDialog('correctData');
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ Button('确定')
|
|
|
|
|
+ .fontColor(Color.White)
|
|
|
|
|
+ .backgroundColor(this.themeColor)
|
|
|
|
|
+ .height(50)
|
|
|
|
|
+ .layoutWeight(1)
|
|
|
|
|
+ .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.7})
|
|
|
|
|
+ .onClick(() => {
|
|
|
|
|
+ this.doCorrectData();
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ .width('100%')
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Text('未发现无效的音乐记录')
|
|
|
|
|
+ .fontColor($r('app.color.text_color'))
|
|
|
|
|
+ .fontSize(16)
|
|
|
|
|
+ .margin({ bottom: 20 })
|
|
|
|
|
+
|
|
|
|
|
+ Button('确定')
|
|
|
|
|
+ .fontColor(Color.White)
|
|
|
|
|
+ .backgroundColor(this.themeColor)
|
|
|
|
|
+ .height(50)
|
|
|
|
|
+ .width('100%')
|
|
|
|
|
+ .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.7})
|
|
|
|
|
+ .onClick(() => {
|
|
|
|
|
+ DialogHelper.closeDialog('correctData');
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .width("100%")
|
|
|
|
|
+ .padding(15)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|