fix(music-houduan): 优化删除功能并添加相关操作

- 在删除音乐、歌单和歌手时,同时删除相关的收藏、点赞和播放历史记录
- 新增按音乐ID、歌单ID和歌手ID删除收藏记录的功能
- 新增按音乐ID删除点赞记录的功能
- 新增按歌单ID删除收藏记录的功能- 优化歌单收藏和取消收藏的逻辑
- 重构部分代码以提高可维护性
This commit is contained in:
ikmkj
2025-08-10 13:27:05 +08:00
parent 876974c4a5
commit 0eae203bd1
9 changed files with 126 additions and 8 deletions

View File

@@ -8,6 +8,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -76,4 +77,14 @@ public interface PlayHistoryRepository extends JpaRepository<PlayHistory, Long>
@Query(value = "INSERT INTO play_history (user_id, music_id, play_time) VALUES (?1, ?2, NOW()) " + @Query(value = "INSERT INTO play_history (user_id, music_id, play_time) VALUES (?1, ?2, NOW()) " +
"ON DUPLICATE KEY UPDATE play_time = NOW()", nativeQuery = true) "ON DUPLICATE KEY UPDATE play_time = NOW()", nativeQuery = true)
void recordPlayHistory(Long userId, Long musicId); void recordPlayHistory(Long userId, Long musicId);
/**
* 根据音乐ID删除播放历史
*
* @param musicId 音乐ID
*/
@Modifying
@Transactional
@Query("DELETE FROM PlayHistory ph WHERE ph.music.id = :musicId")
void deleteByMusicId(@Param("musicId") Long musicId);
} }

View File

@@ -6,7 +6,11 @@ import com.test.musichouduan.entity.UserCollectMusic;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional; import java.util.Optional;
@@ -75,4 +79,14 @@ public interface UserCollectMusicRepository extends JpaRepository<UserCollectMus
* @param music 音乐 * @param music 音乐
*/ */
void deleteByUserAndMusic(User user, Music music); void deleteByUserAndMusic(User user, Music music);
/**
* 根据音乐ID删除收藏记录
*
* @param musicId 音乐ID
*/
@Modifying
@Transactional
@Query("DELETE FROM UserCollectMusic ucm WHERE ucm.music.id = :musicId")
void deleteByMusicId(@Param("musicId") Long musicId);
} }

View File

@@ -8,6 +8,14 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional; import java.util.Optional;
/** /**
@@ -66,4 +74,29 @@ public interface UserCollectPlaylistRepository extends JpaRepository<UserCollect
* @param playlist 歌单 * @param playlist 歌单
*/ */
void deleteByUserAndPlaylist(User user, Playlist playlist); void deleteByUserAndPlaylist(User user, Playlist playlist);
/**
* 根据歌单ID删除收藏记录
*
* @param playlistId 歌单ID
*/
@Modifying
@Transactional
@Query("DELETE FROM UserCollectPlaylist ucp WHERE ucp.playlist.id = :playlistId")
void deleteByPlaylistId(@Param("playlistId") Long playlistId);
boolean existsByUserIdAndPlaylistId(Long userId, Long playlistId);
@Modifying
@Transactional
@Query(value = "INSERT INTO user_collect_playlist (user_id, playlist_id, collect_time) VALUES (?1, ?2, NOW())", nativeQuery = true)
void collectPlaylist(Long userId, Long playlistId);
@Modifying
@Transactional
@Query(value = "DELETE FROM user_collect_playlist WHERE user_id = ?1 AND playlist_id = ?2", nativeQuery = true)
void uncollectPlaylist(Long userId, Long playlistId);
@Query("SELECT ucp.playlist FROM UserCollectPlaylist ucp WHERE ucp.user.id = ?1")
Page<Playlist> findCollectedPlaylist(Long userId, Pageable pageable);
} }

View File

@@ -8,6 +8,14 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional; import java.util.Optional;
/** /**
@@ -66,4 +74,14 @@ public interface UserCollectSingerRepository extends JpaRepository<UserCollectSi
* @param singer 歌手 * @param singer 歌手
*/ */
void deleteByUserAndSinger(User user, Singer singer); void deleteByUserAndSinger(User user, Singer singer);
/**
* 根据歌手ID删除收藏记录
*
* @param singerId 歌手ID
*/
@Modifying
@Transactional
@Query(value = "DELETE FROM user_collect_singer WHERE singer_id = :singerId", nativeQuery = true)
void deleteBySingerId(@Param("singerId") Long singerId);
} }

View File

@@ -2,7 +2,11 @@ package com.test.musichouduan.repository;
import com.test.musichouduan.entity.UserLikeMusic; import com.test.musichouduan.entity.UserLikeMusic;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional; import java.util.Optional;
@@ -26,4 +30,14 @@ public interface UserLikeMusicRepository extends JpaRepository<UserLikeMusic, Lo
* @return 是否存在 * @return 是否存在
*/ */
boolean existsByUserIdAndMusicId(Long userId, Long musicId); boolean existsByUserIdAndMusicId(Long userId, Long musicId);
/**
* 根据音乐ID删除点赞记录
*
* @param musicId 音乐ID
*/
@Modifying
@Transactional
@Query("DELETE FROM UserLikeMusic ulm WHERE ulm.musicId = :musicId")
void deleteByMusicId(@Param("musicId") Long musicId);
} }

View File

@@ -8,6 +8,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -75,4 +76,14 @@ public interface UserSingerRepository extends JpaRepository<UserSinger, Long> {
*/ */
@Query("SELECT us.singer FROM UserSinger us WHERE us.user.id = ?1") @Query("SELECT us.singer FROM UserSinger us WHERE us.user.id = ?1")
Page<Singer> findCollectedSinger(Long userId, Pageable pageable); Page<Singer> findCollectedSinger(Long userId, Pageable pageable);
/**
* 根据歌手ID删除收藏记录
*
* @param singerId 歌手ID
*/
@Modifying
@Transactional
@Query("DELETE FROM UserSinger us WHERE us.singer.id = :singerId")
void deleteBySingerId(@Param("singerId") Long singerId);
} }

View File

@@ -468,6 +468,15 @@ public class MusicServiceImpl implements MusicService {
fileService.deleteFile(music.getCover()); fileService.deleteFile(music.getCover());
} }
// 删除相关的收藏记录
userCollectMusicRepository.deleteByMusicId(id);
// 删除相关的点赞记录
userLikeMusicRepository.deleteByMusicId(id);
// 删除相关的播放历史
playHistoryRepository.deleteByMusicId(id);
// 删除音乐 // 删除音乐
musicRepository.delete(music); musicRepository.delete(music);

View File

@@ -9,6 +9,7 @@ import com.test.musichouduan.entity.Music;
import com.test.musichouduan.entity.Playlist; import com.test.musichouduan.entity.Playlist;
import com.test.musichouduan.entity.PlaylistType; import com.test.musichouduan.entity.PlaylistType;
import com.test.musichouduan.entity.User; import com.test.musichouduan.entity.User;
// No extra imports needed
import com.test.musichouduan.exception.BusinessException; import com.test.musichouduan.exception.BusinessException;
import com.test.musichouduan.repository.*; import com.test.musichouduan.repository.*;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
@@ -70,7 +71,7 @@ public class PlaylistServiceImpl implements PlaylistService {
private UserRepository userRepository; private UserRepository userRepository;
@Autowired @Autowired
private UserPlaylistRepository userPlaylistRepository; private UserCollectPlaylistRepository userCollectPlaylistRepository;
@Autowired @Autowired
private PlayHistoryRepository playHistoryRepository; private PlayHistoryRepository playHistoryRepository;
@@ -344,6 +345,9 @@ public class PlaylistServiceImpl implements PlaylistService {
fileService.deleteFile(playlist.getCover()); fileService.deleteFile(playlist.getCover());
} }
// 删除相关的收藏记录
userCollectPlaylistRepository.deleteByPlaylistId(id);
// 删除歌单 // 删除歌单
playlistRepository.delete(playlist); playlistRepository.delete(playlist);
@@ -363,12 +367,12 @@ public class PlaylistServiceImpl implements PlaylistService {
.orElseThrow(() -> new BusinessException("歌单不存在")); .orElseThrow(() -> new BusinessException("歌单不存在"));
// 检查是否已收藏 // 检查是否已收藏
if (userPlaylistRepository.existsByUserAndPlaylist(user, playlist)) { if (userCollectPlaylistRepository.existsByUserAndPlaylist(user, playlist)) {
throw new BusinessException("已收藏该歌单"); throw new BusinessException("已收藏该歌单");
} }
// 收藏歌单 // 收藏歌单
userPlaylistRepository.collectPlaylist(user.getId(), playlist.getId()); userCollectPlaylistRepository.collectPlaylist(user.getId(), playlist.getId());
// 更新收藏数 // 更新收藏数
playlist.setCollectCount((playlist.getCollectCount() == null ? 0 : playlist.getCollectCount()) + 1); playlist.setCollectCount((playlist.getCollectCount() == null ? 0 : playlist.getCollectCount()) + 1);
@@ -390,12 +394,12 @@ public class PlaylistServiceImpl implements PlaylistService {
.orElseThrow(() -> new BusinessException("歌单不存在")); .orElseThrow(() -> new BusinessException("歌单不存在"));
// 检查是否已收藏 // 检查是否已收藏
if (!userPlaylistRepository.existsByUserAndPlaylist(user, playlist)) { if (!userCollectPlaylistRepository.existsByUserAndPlaylist(user, playlist)) {
throw new BusinessException("未收藏该歌单"); throw new BusinessException("未收藏该歌单");
} }
// 取消收藏歌单 // 取消收藏歌单
userPlaylistRepository.uncollectPlaylist(user.getId(), playlist.getId()); userCollectPlaylistRepository.uncollectPlaylist(user.getId(), playlist.getId());
// 更新收藏数 // 更新收藏数
playlist.setCollectCount((playlist.getCollectCount() == null ? 0 : playlist.getCollectCount()) - 1); playlist.setCollectCount((playlist.getCollectCount() == null ? 0 : playlist.getCollectCount()) - 1);
@@ -410,7 +414,7 @@ public class PlaylistServiceImpl implements PlaylistService {
return false; return false;
} }
Long userId = StpUtil.getLoginIdAsLong(); Long userId = StpUtil.getLoginIdAsLong();
return userPlaylistRepository.existsByUserIdAndPlaylistId(userId, id); return userCollectPlaylistRepository.existsByUserIdAndPlaylistId(userId, id);
} }
@Override @Override
@@ -419,7 +423,7 @@ public class PlaylistServiceImpl implements PlaylistService {
Long userId = StpUtil.getLoginIdAsLong(); Long userId = StpUtil.getLoginIdAsLong();
// 获取用户收藏的歌单 // 获取用户收藏的歌单
Page<Playlist> playlistPage = userPlaylistRepository.findCollectedPlaylist( Page<Playlist> playlistPage = userCollectPlaylistRepository.findCollectedPlaylist(
userId, userId,
PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "collectTime")) PageRequest.of(page - 1, size, Sort.by(Sort.Direction.DESC, "collectTime"))
); );
@@ -606,7 +610,7 @@ public class PlaylistServiceImpl implements PlaylistService {
// 检查当前登录用户是否已收藏该歌单 // 检查当前登录用户是否已收藏该歌单
if (StpUtil.isLogin()) { if (StpUtil.isLogin()) {
Long userId = StpUtil.getLoginIdAsLong(); Long userId = StpUtil.getLoginIdAsLong();
boolean isCollected = userPlaylistRepository.existsByUserIdAndPlaylistId(userId, playlist.getId()); boolean isCollected = userCollectPlaylistRepository.existsByUserIdAndPlaylistId(userId, playlist.getId());
playlistDTO.setIsCollected(isCollected); playlistDTO.setIsCollected(isCollected);
} else { } else {
playlistDTO.setIsCollected(false); playlistDTO.setIsCollected(false);

View File

@@ -7,6 +7,7 @@ import com.test.musichouduan.dto.MusicDTO;
import com.test.musichouduan.entity.Singer; import com.test.musichouduan.entity.Singer;
import com.test.musichouduan.entity.SingerType; import com.test.musichouduan.entity.SingerType;
import com.test.musichouduan.entity.User; import com.test.musichouduan.entity.User;
// No extra imports needed
import com.test.musichouduan.entity.Music; import com.test.musichouduan.entity.Music;
import com.test.musichouduan.exception.BusinessException; import com.test.musichouduan.exception.BusinessException;
import com.test.musichouduan.repository.MusicRepository; import com.test.musichouduan.repository.MusicRepository;
@@ -293,6 +294,9 @@ public class SingerServiceImpl implements SingerService {
fileService.deleteFile(singer.getAvatar()); fileService.deleteFile(singer.getAvatar());
} }
// 删除相关的收藏记录
userSingerRepository.deleteBySingerId(id);
// 删除歌手 // 删除歌手
singerRepository.delete(singer); singerRepository.delete(singer);