216 lines
7.3 KiB
Java
216 lines
7.3 KiB
Java
package com.guwan.backend.service.impl;
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
import com.guwan.backend.annotation.OperationLog;
|
|
import com.guwan.backend.dto.video.VideoDTO;
|
|
import com.guwan.backend.entity.Video;
|
|
import com.guwan.backend.entity.VideoLike;
|
|
import com.guwan.backend.mapper.VideoLikeMapper;
|
|
import com.guwan.backend.mapper.VideoMapper;
|
|
import com.guwan.backend.service.VideoService;
|
|
import com.guwan.backend.util.MinioUtil;
|
|
import com.guwan.backend.util.SecurityUtil;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.beans.BeanUtils;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
@Slf4j
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
public class VideoServiceImpl implements VideoService {
|
|
|
|
private final VideoMapper videoMapper;
|
|
private final MinioUtil minioUtil;
|
|
private final SecurityUtil securityUtil;
|
|
private final VideoLikeMapper videoLikeMapper;
|
|
|
|
@Override
|
|
@Transactional
|
|
@OperationLog(description = "上传视频", operationType = "上传")
|
|
public VideoDTO uploadVideo(MultipartFile file, String title, String description, String tags) {
|
|
// 获取当前用户
|
|
Long userId = securityUtil.getCurrentUserId();
|
|
if (userId == null) {
|
|
throw new IllegalStateException("用户未登录");
|
|
}
|
|
|
|
try {
|
|
// 上传视频文件到MinIO
|
|
String fileName = minioUtil.uploadFile("videos", file);
|
|
String url = minioUtil.getUrl(minioUtil.getFileUrl("videos", fileName));
|
|
|
|
// 创建视频记录
|
|
Video video = new Video();
|
|
video.setTitle(title);
|
|
video.setDescription(description);
|
|
video.setUrl(url);
|
|
video.setSize(file.getSize());
|
|
video.setUserId(userId);
|
|
video.setStatus("PUBLISHED");
|
|
video.setTags(tags);
|
|
video.setViewCount(0);
|
|
video.setLikeCount(0);
|
|
|
|
videoMapper.insert(video);
|
|
|
|
return convertToDTO(video);
|
|
} catch (Exception e) {
|
|
log.error("上传视频失败", e);
|
|
throw new RuntimeException("上传视频失败", e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@Transactional
|
|
@OperationLog(description = "更新视频信息", operationType = "更新")
|
|
public VideoDTO updateVideo(VideoDTO videoDTO) {
|
|
Video video = videoMapper.selectById(videoDTO.getId());
|
|
if (video == null) {
|
|
throw new IllegalArgumentException("视频不存在");
|
|
}
|
|
|
|
// 检查权限
|
|
Long currentUserId = securityUtil.getCurrentUserId();
|
|
if (!video.getUserId().equals(currentUserId)) {
|
|
throw new IllegalStateException("无权修改此视频");
|
|
}
|
|
|
|
BeanUtils.copyProperties(videoDTO, video, "id", "userId", "url", "createdTime");
|
|
videoMapper.updateById(video);
|
|
|
|
return convertToDTO(video);
|
|
}
|
|
|
|
@Override
|
|
@Transactional
|
|
@OperationLog(description = "删除视频", operationType = "删除")
|
|
public void deleteVideo(Long id) {
|
|
Video video = videoMapper.selectById(id);
|
|
if (video == null) {
|
|
return;
|
|
}
|
|
|
|
// 检查权限
|
|
Long currentUserId = securityUtil.getCurrentUserId();
|
|
if (!video.getUserId().equals(currentUserId)) {
|
|
throw new IllegalStateException("无权删除此视频");
|
|
}
|
|
|
|
// 从MinIO中删除视频文件
|
|
String fileName = video.getUrl().substring(video.getUrl().lastIndexOf("/") + 1);
|
|
minioUtil.deleteFile("videos", fileName);
|
|
|
|
// 删除数据库记录
|
|
videoMapper.deleteById(id);
|
|
}
|
|
|
|
@Override
|
|
@OperationLog(description = "获取视频详情", operationType = "查询")
|
|
public VideoDTO getVideoById(Long id) {
|
|
Video video = videoMapper.selectById(id);
|
|
return convertToDTO(video);
|
|
}
|
|
|
|
@Override
|
|
@OperationLog(description = "获取视频列表", operationType = "查询")
|
|
public IPage<VideoDTO> getVideoList(Integer pageNum, Integer pageSize, String keyword) {
|
|
Page<Video> page = new Page<>(pageNum, pageSize);
|
|
|
|
LambdaQueryWrapper<Video> wrapper = new LambdaQueryWrapper<Video>()
|
|
.eq(Video::getStatus, "PUBLISHED")
|
|
.like(keyword != null, Video::getTitle, keyword)
|
|
.or()
|
|
.like(keyword != null, Video::getDescription, keyword)
|
|
.orderByDesc(Video::getCreatedTime);
|
|
|
|
IPage<Video> videoPage = videoMapper.selectPage(page, wrapper);
|
|
|
|
return videoPage.convert(this::convertToDTO);
|
|
}
|
|
|
|
@Override
|
|
@Transactional
|
|
@OperationLog(description = "增加视频观看次数", operationType = "更新")
|
|
public void incrementViewCount(Long id) {
|
|
Video video = videoMapper.selectById(id);
|
|
if (video != null) {
|
|
video.setViewCount(video.getViewCount() + 1);
|
|
videoMapper.updateById(video);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@Transactional
|
|
@OperationLog(description = "视频点赞/取消点赞", operationType = "更新")
|
|
public void toggleLike(Long id) {
|
|
// 获取当前用户
|
|
Long userId = securityUtil.getCurrentUserId();
|
|
if (userId == null) {
|
|
throw new IllegalStateException("用户未登录");
|
|
}
|
|
|
|
// 检查视频是否存在
|
|
Video video = videoMapper.selectById(id);
|
|
if (video == null) {
|
|
throw new IllegalArgumentException("视频不存在");
|
|
}
|
|
|
|
// 检查是否已点赞
|
|
LambdaQueryWrapper<VideoLike> wrapper = new LambdaQueryWrapper<VideoLike>()
|
|
.eq(VideoLike::getVideoId, id)
|
|
.eq(VideoLike::getUserId, userId);
|
|
|
|
VideoLike like = videoLikeMapper.selectOne(wrapper);
|
|
|
|
if (like == null) {
|
|
// 未点赞,添加点赞记录
|
|
like = new VideoLike();
|
|
like.setVideoId(id);
|
|
like.setUserId(userId);
|
|
videoLikeMapper.insert(like);
|
|
|
|
// 更新视频点赞数
|
|
video.setLikeCount(video.getLikeCount() + 1);
|
|
} else {
|
|
// 已点赞,取消点赞
|
|
videoLikeMapper.deleteById(like.getId());
|
|
|
|
// 更新视频点赞数
|
|
video.setLikeCount(video.getLikeCount() - 1);
|
|
}
|
|
|
|
videoMapper.updateById(video);
|
|
}
|
|
|
|
// 添加新方法:检查用户是否已点赞
|
|
public boolean hasLiked(Long videoId) {
|
|
Long userId = securityUtil.getCurrentUserId();
|
|
if (userId == null) {
|
|
return false;
|
|
}
|
|
|
|
LambdaQueryWrapper<VideoLike> wrapper = new LambdaQueryWrapper<VideoLike>()
|
|
.eq(VideoLike::getVideoId, videoId)
|
|
.eq(VideoLike::getUserId, userId);
|
|
|
|
return videoLikeMapper.selectCount(wrapper) > 0;
|
|
}
|
|
|
|
private VideoDTO convertToDTO(Video video) {
|
|
if (video == null) {
|
|
return null;
|
|
}
|
|
VideoDTO dto = new VideoDTO();
|
|
BeanUtils.copyProperties(video, dto);
|
|
|
|
// 设置是否已点赞
|
|
// dto.setHasLiked(hasLiked(video.getId()));
|
|
|
|
return dto;
|
|
}
|
|
} |