|
|
@@ -1292,97 +1292,7 @@ export default class MediaTable {
|
|
|
* 返回艺术家封面列表的代表性歌曲
|
|
|
*/
|
|
|
public async queryArtistsPaged(options: PageQueryOptions): Promise<PageQueryResult> {
|
|
|
- try {
|
|
|
- Logger.info('heanup MediaTable', `queryArtistsPaged: 开始分页查询 page=${options.pageIndex}, size=${options.pageSize}`);
|
|
|
-
|
|
|
- // 艺术家模式:返回每个艺术家的第一首歌作为代表
|
|
|
- // 先查询所有不同的艺术家
|
|
|
- const artistPredicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
|
|
|
- artistPredicates.isNotNull(DB_COLUMNS.ARTIST);
|
|
|
- artistPredicates.notEqualTo(DB_COLUMNS.ARTIST, '');
|
|
|
- artistPredicates.distinct();
|
|
|
-
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- this.accountTable.query(artistPredicates, async (resultSet: relationalStore.ResultSet) => {
|
|
|
- try {
|
|
|
- const artists: string[] = this.parseDistinctColumn(resultSet, DB_COLUMNS.ARTIST);
|
|
|
-
|
|
|
- // 应用搜索过滤
|
|
|
- let filteredArtists = artists;
|
|
|
- if (options.searchKeyword) {
|
|
|
- const keyword = options.searchKeyword.toLowerCase();
|
|
|
- filteredArtists = artists.filter(artist =>
|
|
|
- artist.toLowerCase().includes(keyword)
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- // 排序
|
|
|
- let allCountMap: Map<string, number> | undefined = undefined;
|
|
|
- if (options.sortType === 8 || options.sortType === 9) {
|
|
|
- allCountMap = new Map<string, number>();
|
|
|
- for (const artist of filteredArtists) {
|
|
|
- const count = await this.getCountByColumn(DB_COLUMNS.ARTIST, artist);
|
|
|
- allCountMap.set(artist, count);
|
|
|
- }
|
|
|
- filteredArtists.sort((a, b) => {
|
|
|
- const countA = allCountMap?.get(a) ?? 0;
|
|
|
- const countB = allCountMap?.get(b) ?? 0;
|
|
|
- const diff = options.sortType === 8 ? countA - countB : countB - countA;
|
|
|
- return diff !== 0 ? diff : a.localeCompare(b);
|
|
|
- });
|
|
|
- } else if (options.sortType === 5) {
|
|
|
- filteredArtists.sort((a, b) => b.localeCompare(a));
|
|
|
- } else {
|
|
|
- filteredArtists.sort((a, b) => a.localeCompare(b));
|
|
|
- }
|
|
|
-
|
|
|
- const totalCount = filteredArtists.length;
|
|
|
- const offset = options.pageIndex * options.pageSize;
|
|
|
- const pagedArtists = filteredArtists.slice(offset, offset + options.pageSize);
|
|
|
-
|
|
|
- // 为每个艺术家查询第一首歌,作为封面来源
|
|
|
- const items: VideoItem[] = [];
|
|
|
- const countMap = new Map<string, number>();
|
|
|
- for (const artist of pagedArtists) {
|
|
|
- const songPredicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
|
|
|
- songPredicates.equalTo(DB_COLUMNS.ARTIST, artist);
|
|
|
- songPredicates.limitAs(1);
|
|
|
-
|
|
|
- let coverPath = '';
|
|
|
- await new Promise<void>((resolveInner) => {
|
|
|
- this.accountTable.query(songPredicates, (songResultSet: relationalStore.ResultSet) => {
|
|
|
- if (songResultSet.rowCount > 0) {
|
|
|
- songResultSet.goToFirstRow();
|
|
|
- const item = this.buildVideoItem(songResultSet);
|
|
|
- coverPath = item.pixelMapPath ?? '';
|
|
|
- }
|
|
|
- songResultSet.close();
|
|
|
- resolveInner();
|
|
|
- });
|
|
|
- });
|
|
|
- const artistSongCount = allCountMap?.get(artist) ?? await this.getCountByColumn(DB_COLUMNS.ARTIST, artist);
|
|
|
- countMap.set(artist, artistSongCount);
|
|
|
- const artistItem = new VideoItem(artist, artist, artist, CommonConstants.TYPE_IS_ARTIST, 0, '');
|
|
|
- artistItem.pixelMapPath = coverPath;
|
|
|
- artistItem.artist = artist;
|
|
|
- items.push(artistItem);
|
|
|
- }
|
|
|
-
|
|
|
- const hasMore = (offset + items.length) < totalCount;
|
|
|
- Logger.info('heanup MediaTable', `queryArtistsPaged: 查询完成 items=${items.length}, total=${totalCount}, hasMore=${hasMore}`);
|
|
|
- resolve({ items, totalCount, hasMore, countMap });
|
|
|
- } catch (err) {
|
|
|
- const error = err as Error;
|
|
|
- Logger.error('heanup MediaTable', `queryArtistsPaged error: ${error.message}`);
|
|
|
- reject(err);
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
- } catch (err) {
|
|
|
- const error = err as Error;
|
|
|
- Logger.error('heanup MediaTable', `queryArtistsPaged failed: ${error.message}`);
|
|
|
- throw error;
|
|
|
- }
|
|
|
+ return await this.queryGroupedPaged(DB_COLUMNS.ARTIST, CommonConstants.TYPE_IS_ARTIST, options);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -1390,95 +1300,85 @@ export default class MediaTable {
|
|
|
* 返回专辑封面列表的代表性歌曲
|
|
|
*/
|
|
|
public async queryAlbumsPaged(options: PageQueryOptions): Promise<PageQueryResult> {
|
|
|
+ return await this.queryGroupedPaged(DB_COLUMNS.ALBUM, CommonConstants.TYPE_IS_ALBUM, options);
|
|
|
+ }
|
|
|
+
|
|
|
+ private async queryGroupedPaged(columnName: string, itemType: number, options: PageQueryOptions): Promise<PageQueryResult> {
|
|
|
try {
|
|
|
- Logger.info('heanup MediaTable', `queryAlbumsPaged: 开始分页查询 page=${options.pageIndex}, size=${options.pageSize}`);
|
|
|
-
|
|
|
- // 专辑模式:返回每个专辑的第一首歌作为代表
|
|
|
- // 先查询所有不同的专辑
|
|
|
- const albumPredicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
|
|
|
- albumPredicates.isNotNull(DB_COLUMNS.ALBUM);
|
|
|
- albumPredicates.notEqualTo(DB_COLUMNS.ALBUM, '');
|
|
|
- albumPredicates.distinct();
|
|
|
-
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- this.accountTable.query(albumPredicates, async (resultSet: relationalStore.ResultSet) => {
|
|
|
- try {
|
|
|
- const albums: string[] = this.parseDistinctColumn(resultSet, DB_COLUMNS.ALBUM);
|
|
|
-
|
|
|
- // 应用搜索过滤
|
|
|
- let filteredAlbums = albums;
|
|
|
- if (options.searchKeyword) {
|
|
|
- const keyword = options.searchKeyword.toLowerCase();
|
|
|
- filteredAlbums = albums.filter(album =>
|
|
|
- album.toLowerCase().includes(keyword)
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- // 排序
|
|
|
- let allCountMap: Map<string, number> | undefined = undefined;
|
|
|
- if (options.sortType === 8 || options.sortType === 9) {
|
|
|
- allCountMap = new Map<string, number>();
|
|
|
- for (const album of filteredAlbums) {
|
|
|
- const count = await this.getCountByColumn(DB_COLUMNS.ALBUM, album);
|
|
|
- allCountMap.set(album, count);
|
|
|
- }
|
|
|
- filteredAlbums.sort((a, b) => {
|
|
|
- const countA = allCountMap?.get(a) ?? 0;
|
|
|
- const countB = allCountMap?.get(b) ?? 0;
|
|
|
- const diff = options.sortType === 8 ? countA - countB : countB - countA;
|
|
|
- return diff !== 0 ? diff : a.localeCompare(b);
|
|
|
- });
|
|
|
- } else if (options.sortType === 5) {
|
|
|
- filteredAlbums.sort((a, b) => b.localeCompare(a));
|
|
|
- } else {
|
|
|
- filteredAlbums.sort((a, b) => a.localeCompare(b));
|
|
|
- }
|
|
|
-
|
|
|
- const totalCount = filteredAlbums.length;
|
|
|
- const offset = options.pageIndex * options.pageSize;
|
|
|
- const pagedAlbums = filteredAlbums.slice(offset, offset + options.pageSize);
|
|
|
-
|
|
|
- // 为每个专辑查询第一首歌,作为封面来源
|
|
|
- const items: VideoItem[] = [];
|
|
|
- const countMap = new Map<string, number>();
|
|
|
- for (const album of pagedAlbums) {
|
|
|
- const songPredicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
|
|
|
- songPredicates.equalTo(DB_COLUMNS.ALBUM, album);
|
|
|
- songPredicates.limitAs(1);
|
|
|
-
|
|
|
- let coverPath = '';
|
|
|
- await new Promise<void>((resolveInner) => {
|
|
|
- this.accountTable.query(songPredicates, (songResultSet: relationalStore.ResultSet) => {
|
|
|
- if (songResultSet.rowCount > 0) {
|
|
|
- songResultSet.goToFirstRow();
|
|
|
- const item = this.buildVideoItem(songResultSet);
|
|
|
- coverPath = item.pixelMapPath ?? '';
|
|
|
- }
|
|
|
- songResultSet.close();
|
|
|
- resolveInner();
|
|
|
- });
|
|
|
- });
|
|
|
- const albumSongCount = allCountMap?.get(album) ?? await this.getCountByColumn(DB_COLUMNS.ALBUM, album);
|
|
|
- countMap.set(album, albumSongCount);
|
|
|
- const albumItem = new VideoItem(album, album, album, CommonConstants.TYPE_IS_ALBUM, 0, '');
|
|
|
- albumItem.pixelMapPath = coverPath;
|
|
|
- albumItem.album = album;
|
|
|
- items.push(albumItem);
|
|
|
- }
|
|
|
-
|
|
|
- const hasMore = (offset + items.length) < totalCount;
|
|
|
- Logger.info('heanup MediaTable', `queryAlbumsPaged: 查询完成 items=${items.length}, total=${totalCount}, hasMore=${hasMore}`);
|
|
|
- resolve({ items, totalCount, hasMore, countMap });
|
|
|
- } catch (err) {
|
|
|
- const error = err as Error;
|
|
|
- Logger.error('heanup MediaTable', `queryAlbumsPaged error: ${error.message}`);
|
|
|
- reject(err);
|
|
|
+ const keyword = options.searchKeyword?.trim();
|
|
|
+ const tableName = RdbUtils.MEDIA_TABLE.tableName;
|
|
|
+ const whereClauses = [
|
|
|
+ `${columnName} IS NOT NULL`,
|
|
|
+ `${columnName} != ''`,
|
|
|
+ `${DB_COLUMNS.TYPE} = ?`
|
|
|
+ ];
|
|
|
+ const params: Array<string | number> = [CommonConstants.TYPE_LOCAL];
|
|
|
+ if (keyword) {
|
|
|
+ whereClauses.push(`${columnName} LIKE ?`);
|
|
|
+ params.push(`%${keyword}%`);
|
|
|
+ }
|
|
|
+ const whereSql = whereClauses.join(' AND ');
|
|
|
+
|
|
|
+ const totalSql = `SELECT COUNT(DISTINCT ${columnName}) AS totalCount FROM ${tableName} WHERE ${whereSql}`;
|
|
|
+ const totalResultSet = await this.accountTable.querySql(totalSql, params);
|
|
|
+ let totalCount = 0;
|
|
|
+ if (totalResultSet.goToFirstRow()) {
|
|
|
+ totalCount = totalResultSet.getLong(totalResultSet.getColumnIndex('totalCount'));
|
|
|
+ }
|
|
|
+ totalResultSet.close();
|
|
|
+
|
|
|
+ const sortType = options.sortType ?? 9;
|
|
|
+ let orderBy = `${columnName} ASC`;
|
|
|
+ if (sortType === 5) {
|
|
|
+ orderBy = `${columnName} DESC`;
|
|
|
+ } else if (sortType === 8) {
|
|
|
+ orderBy = `songCount ASC, ${columnName} ASC`;
|
|
|
+ } else if (sortType === 9) {
|
|
|
+ orderBy = `songCount DESC, ${columnName} ASC`;
|
|
|
+ }
|
|
|
+
|
|
|
+ const offset = options.pageIndex * options.pageSize;
|
|
|
+ const pageSql =
|
|
|
+ `SELECT ${columnName} AS name, COUNT(*) AS songCount, ` +
|
|
|
+ `MAX(${DB_COLUMNS.PIXEL_MAP_PATH}) AS coverPath ` +
|
|
|
+ `FROM ${tableName} WHERE ${whereSql} ` +
|
|
|
+ `GROUP BY ${columnName} ` +
|
|
|
+ `HAVING COUNT(*) > 0 ` +
|
|
|
+ `ORDER BY ${orderBy} ` +
|
|
|
+ `LIMIT ? OFFSET ?`;
|
|
|
+ const pageParams = [...params, options.pageSize, offset];
|
|
|
+ const resultSet = await this.accountTable.querySql(pageSql, pageParams);
|
|
|
+
|
|
|
+ const items: VideoItem[] = [];
|
|
|
+ const countMap = new Map<string, number>();
|
|
|
+ if (resultSet.rowCount > 0) {
|
|
|
+ resultSet.goToFirstRow();
|
|
|
+ for (let i = 0; i < resultSet.rowCount; i++) {
|
|
|
+ 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);
|
|
|
+ const item = new VideoItem(name, name, name, itemType, 0, '');
|
|
|
+ item.pixelMapPath = coverPath;
|
|
|
+ if (itemType === CommonConstants.TYPE_IS_ARTIST) {
|
|
|
+ item.artist = name;
|
|
|
+ } else {
|
|
|
+ item.album = name;
|
|
|
}
|
|
|
- });
|
|
|
- });
|
|
|
+ items.push(item);
|
|
|
+ if (i < resultSet.rowCount - 1) {
|
|
|
+ resultSet.goToNextRow();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ resultSet.close();
|
|
|
+
|
|
|
+ const hasMore = (offset + items.length) < totalCount;
|
|
|
+ Logger.info('heanup MediaTable', `queryGroupedPaged: 查询完成 items=${items.length}, total=${totalCount}, hasMore=${hasMore}`);
|
|
|
+ return { items, totalCount, hasMore, countMap };
|
|
|
} catch (err) {
|
|
|
const error = err as Error;
|
|
|
- Logger.error('heanup MediaTable', `queryAlbumsPaged failed: ${error.message}`);
|
|
|
+ Logger.error('heanup MediaTable', `queryGroupedPaged failed: ${error.message}`);
|
|
|
throw error;
|
|
|
}
|
|
|
}
|