feat(search): 实现歌单搜索功能

- 在前端 Playlist.vue 中添加搜索结果展示逻辑
- 在后端 PlaylistServiceImpl 中实现关键词搜索的查询条件
- 优化搜索性能,使用 distinct 查询避免重复结果
- 搜索范围包括歌单名、描述、创建者用户名以及歌单内的音乐名
This commit is contained in:
ikmkj
2025-07-29 19:48:43 +08:00
parent e8c66e0dd2
commit 8aa076ded1
3 changed files with 16 additions and 9 deletions

View File

@@ -33,12 +33,12 @@
</dependency>
<!-- 开发工具 -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-devtools</artifactId>-->
<!-- <scope>runtime</scope>-->
<!-- <optional>true</optional>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- Lombok -->
<dependency>

View File

@@ -90,10 +90,16 @@ public class PlaylistServiceImpl implements PlaylistService {
// 构建查询条件
Specification<Playlist> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
query.distinct(true); // 添加 distinct 查询
// 关键字查询
if (StringUtils.hasText(keyword)) {
predicates.add(cb.like(root.get("name"), "%" + keyword + "%"));
// 搜索歌单名、描述、创建者用户名以及歌单内的音乐名
Predicate p1 = cb.like(root.get("name"), "%" + keyword + "%");
Predicate p2 = cb.like(root.get("description"), "%" + keyword + "%");
Predicate p3 = cb.like(root.join("creator").get("username"), "%" + keyword + "%");
Predicate p4 = cb.like(root.join("musics", jakarta.persistence.criteria.JoinType.LEFT).get("name"), "%" + keyword + "%");
predicates.add(cb.or(p1, p2, p3, p4));
}
// 类型查询

View File

@@ -243,7 +243,7 @@ onMounted(() => {
</div>
<!-- 热门歌单 -->
<div class="hot-playlists" v-if="activeType === null && currentPage === 1">
<div class="hot-playlists" v-if="!keyword && activeType === null && currentPage === 1">
<h2>热门歌单</h2>
<div class="playlist-list" v-loading="loadingHot">
<div
@@ -291,7 +291,8 @@ onMounted(() => {
<!-- 歌单列表 -->
<div class="all-playlists">
<h2 v-if="activeType === null && currentPage === 1">全部歌单</h2>
<h2 v-if="keyword">搜索结果</h2>
<h2 v-else-if="activeType === null && currentPage === 1">全部歌单</h2>
<div class="playlist-list" v-loading="loading">
<div
v-for="playlist in playlists"