瀏覽代碼

修复道理鱼艺术家点进去无歌曲

chendeben 6 月之前
父節點
當前提交
664af1d903

+ 28 - 6
entry/src/main/ets/common/network/DaoLiYuApi.ets

@@ -293,31 +293,53 @@ export class DaoLiYuApi {
       .map(track => this.mapTrack(track as DaoLiYuTrackEntry));
   }
 
-  async getTracksByAlbumId(account: WebDavAccount, albumId: string, limit: number = 0): Promise<DaoLiYuTrack[]> {
-    if (!albumId) {
+  async getTracksByAlbumId(account: WebDavAccount, albumId: string, albumName?: string, limit: number = 0): Promise<DaoLiYuTrack[]> {
+    if (!albumId && !albumName) {
       return [];
     }
     const matches: DaoLiYuTrack[] = [];
+    // 用于名称匹配的规范化名称(去除前后空格,转小写)
+    const normalizedName = albumName?.trim().toLowerCase();
     await this.scanTracks(account, limit, track => {
-      if (track.albumId === albumId) {
+      // 优先按 albumId 匹配
+      if (albumId && track.albumId === albumId) {
         matches.push(track);
         return true;
       }
+      // 后备:按专辑名称匹配(处理 albumId 为空的情况)
+      if (normalizedName && track.album) {
+        const trackAlbumName = track.album.trim().toLowerCase();
+        if (trackAlbumName === normalizedName) {
+          matches.push(track);
+          return true;
+        }
+      }
       return false;
     });
     return matches;
   }
 
-  async getTracksByArtistId(account: WebDavAccount, artistId: string, limit: number = 0): Promise<DaoLiYuTrack[]> {
-    if (!artistId) {
+  async getTracksByArtistId(account: WebDavAccount, artistId: string, artistName?: string, limit: number = 0): Promise<DaoLiYuTrack[]> {
+    if (!artistId && !artistName) {
       return [];
     }
     const matches: DaoLiYuTrack[] = [];
+    // 用于名称匹配的规范化名称(去除前后空格,转小写)
+    const normalizedName = artistName?.trim().toLowerCase();
     await this.scanTracks(account, limit, track => {
-      if (track.artistId === artistId) {
+      // 优先按 artistId 匹配
+      if (artistId && track.artistId === artistId) {
         matches.push(track);
         return true;
       }
+      // 后备:按艺术家名称匹配(处理 artistId 为空的情况)
+      if (normalizedName && track.artist) {
+        const trackArtistName = track.artist.trim().toLowerCase();
+        if (trackArtistName === normalizedName) {
+          matches.push(track);
+          return true;
+        }
+      }
       return false;
     });
     return matches;

+ 55 - 38
entry/src/main/ets/common/util/MediaTable.ets

@@ -619,23 +619,31 @@ export default  class MediaTable {
    */
   public async querySongsByArtist(artist: string, sortType?: number, isShowFileName?: boolean): Promise<VideoItem[]> {
     try {
-      const predicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
-      predicates.equalTo(DB_COLUMNS.ARTIST, artist);
-      predicates.equalTo(DB_COLUMNS.TYPE, CommonConstants.TYPE_LOCAL);
-      this.applySortConditions(predicates, sortType, isShowFileName);
+      const trimmedArtist = artist?.trim() || '';
+      if (!trimmedArtist) {
+        return [];
+      }
 
-      return await new Promise((resolve, reject) => {
-        this.accountTable.query(predicates, (resultSet: relationalStore.ResultSet) => {
-          try {
-            const result = this.parseResultSetToVideoItems(resultSet, sortType);
-            resolve(result);
-          } catch (err) {
-            reject(err);
-          }
-        });
-      });
+      // 使用SQL的TRIM函数匹配,解决数据库中artist字段可能有前后空格的问题
+      const tableName = RdbUtils.MEDIA_TABLE.tableName;
+      let orderBy = `${DB_COLUMNS.NAME} COLLATE NOCASE ASC`;
+      if (isShowFileName) {
+        orderBy = `${DB_COLUMNS.FILE_NAME} COLLATE NOCASE ASC`;
+      }
+
+      const sql = `SELECT * FROM ${tableName} WHERE TRIM(${DB_COLUMNS.ARTIST}) = ? AND ${DB_COLUMNS.TYPE} = ? ORDER BY ${orderBy}`;
+      const params: (string | number)[] = [trimmedArtist, CommonConstants.TYPE_LOCAL];
+
+      const resultSet = await this.accountTable.querySql(sql, params);
+      try {
+        const result = this.parseResultSetToVideoItems(resultSet, sortType);
+        return result;
+      } finally {
+        resultSet.close();
+      }
     } catch (err) {
-      Logger.error(`querySongsByArtist error: ${err.code}  - ${err.message}`);
+      const error = err as Error;
+      Logger.error('heanup MediaTable', `querySongsByArtist error: ${error.message}`);
       return [];
     }
   }
@@ -645,23 +653,31 @@ export default  class MediaTable {
    */
   public async querySongsByAlbum(album: string, sortType?: number, isShowFileName?: boolean): Promise<VideoItem[]> {
     try {
-      const predicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
-      predicates.equalTo(DB_COLUMNS.ALBUM, album);
-      predicates.equalTo(DB_COLUMNS.TYPE, CommonConstants.TYPE_LOCAL);
-      this.applySortConditions(predicates, sortType, isShowFileName);
+      const trimmedAlbum = album?.trim() || '';
+      if (!trimmedAlbum) {
+        return [];
+      }
 
-      return await new Promise((resolve, reject) => {
-        this.accountTable.query(predicates, (resultSet: relationalStore.ResultSet) => {
-          try {
-            const result = this.parseResultSetToVideoItems(resultSet, sortType);
-            resolve(result);
-          } catch (err) {
-            reject(err);
-          }
-        });
-      });
+      // 使用SQL的TRIM函数匹配,解决数据库中album字段可能有前后空格的问题
+      const tableName = RdbUtils.MEDIA_TABLE.tableName;
+      let orderBy = `${DB_COLUMNS.NAME} COLLATE NOCASE ASC`;
+      if (isShowFileName) {
+        orderBy = `${DB_COLUMNS.FILE_NAME} COLLATE NOCASE ASC`;
+      }
+
+      const sql = `SELECT * FROM ${tableName} WHERE TRIM(${DB_COLUMNS.ALBUM}) = ? AND ${DB_COLUMNS.TYPE} = ? ORDER BY ${orderBy}`;
+      const params: (string | number)[] = [trimmedAlbum, CommonConstants.TYPE_LOCAL];
+
+      const resultSet = await this.accountTable.querySql(sql, params);
+      try {
+        const result = this.parseResultSetToVideoItems(resultSet, sortType);
+        return result;
+      } finally {
+        resultSet.close();
+      }
     } catch (err) {
-      Logger.error(`querySongsByAlbum error: ${err.code}  - ${err.message}`);
+      const error = err as Error;
+      Logger.error('heanup MediaTable', `querySongsByAlbum error: ${error.message}`);
       return [];
     }
   }
@@ -1506,7 +1522,8 @@ export default  class MediaTable {
       }
       const whereSql = whereClauses.join(' AND ');
 
-      const totalSql = `SELECT COUNT(DISTINCT ${columnName}) AS totalCount FROM ${tableName} WHERE ${whereSql}`;
+      // 使用TRIM函数去除空格,合并相同艺术家/专辑名的数据
+      const totalSql = `SELECT COUNT(DISTINCT TRIM(${columnName})) AS totalCount FROM ${tableName} WHERE ${whereSql}`;
       const totalResultSet = await this.accountTable.querySql(totalSql, params);
       let totalCount = 0;
       if (totalResultSet.goToFirstRow()) {
@@ -1515,21 +1532,21 @@ export default  class MediaTable {
       totalResultSet.close();
 
       const sortType = options.sortType ?? 9;
-      let orderBy = `${columnName} ASC`;
+      let orderBy = `name ASC`;
       if (sortType === 5) {
-        orderBy = `${columnName} DESC`;
+        orderBy = `name DESC`;
       } else if (sortType === 8) {
-        orderBy = `songCount ASC, ${columnName} ASC`;
+        orderBy = `songCount ASC, name ASC`;
       } else if (sortType === 9) {
-        orderBy = `songCount DESC, ${columnName} ASC`;
+        orderBy = `songCount DESC, name ASC`;
       }
 
       const offset = options.pageIndex * options.pageSize;
       const pageSql =
-        `SELECT ${columnName} AS name, COUNT(*) AS songCount, ` +
+        `SELECT TRIM(${columnName}) AS name, COUNT(*) AS songCount, ` +
         `MAX(${DB_COLUMNS.PIXEL_MAP_PATH}) AS coverPath ` +
         `FROM ${tableName} WHERE ${whereSql} ` +
-        `GROUP BY ${columnName} ` +
+        `GROUP BY TRIM(${columnName}) ` +
         `HAVING COUNT(*) > 0 ` +
         `ORDER BY ${orderBy} ` +
         `LIMIT ? OFFSET ?`;
@@ -1541,7 +1558,7 @@ export default  class MediaTable {
       if (resultSet.rowCount > 0) {
         resultSet.goToFirstRow();
         for (let i = 0; i < resultSet.rowCount; i++) {
-          const name = resultSet.getString(resultSet.getColumnIndex('name'));
+          const name = resultSet.getString(resultSet.getColumnIndex('name')) || '';
           const songCount = resultSet.getLong(resultSet.getColumnIndex('songCount'));
           const coverPath = resultSet.getString(resultSet.getColumnIndex('coverPath')) || '';
           countMap.set(name, songCount);

+ 4 - 2
entry/src/main/ets/view/NavidromePage.ets

@@ -3130,7 +3130,8 @@ export struct NavidromePage {
           const songs = await this.fetchAllPlexArtistSongs(account, this.filterId);
           restSongs = this.convertPlexSongsToRestSongs(songs);
         } else if (this.isDaoLiYuAccount(account)) {
-          const songs = await daoLiYuApi.getTracksByArtistId(account, this.filterId);
+          // 同时传递 artistId 和 artistName,支持按名称匹配作为后备
+          const songs = await daoLiYuApi.getTracksByArtistId(account, this.filterId, label);
           restSongs = this.convertDaoLiYuSongsToRestSongs(songs);
         }
       } else if (this.filterType === NavFilterType.Album) {
@@ -3148,7 +3149,8 @@ export struct NavidromePage {
           const songs = await plexApi.getAlbumSongs(account, this.filterId);
           restSongs = this.convertPlexSongsToRestSongs(songs);
         } else if (this.isDaoLiYuAccount(account)) {
-          const songs = await daoLiYuApi.getTracksByAlbumId(account, this.filterId);
+          // 同时传递 albumId 和 albumName,支持按名称匹配作为后备
+          const songs = await daoLiYuApi.getTracksByAlbumId(account, this.filterId, label);
           restSongs = this.convertDaoLiYuSongsToRestSongs(songs);
         }
       } else if (this.filterType === NavFilterType.Playlist) {