
管理员
站长
- UID
- 1
- 积分
- 224315
- 余额
- 13 R
- Moe币
- 84800
- 在线时间
- 264 小时
- 注册时间
- 2025-12-28
- 最后登录
- 2026-9-19
|
package com.mg1.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.mg1.common.teen.TeenGuard;
import com.mg1.dto.CommentPageDTO;
import com.mg1.entity.Comment;
import com.mg1.entity.CommentLike;
import com.mg1.entity.Manga;
import com.mg1.entity.User;
import com.mg1.mapper.CommentLikeMapper;
import com.mg1.mapper.CommentMapper;
import com.mg1.mapper.MangaMapper;
import com.mg1.mapper.UserMapper;
import com.mg1.service.CommentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class CommentServiceImpl implements CommentService {
private final CommentMapper commentMapper;
private final CommentLikeMapper commentLikeMapper;
private final UserMapper userMapper;
private final MangaMapper mangaMapper;
private final TeenGuard teenGuard;
public CommentServiceImpl(CommentMapper commentMapper, CommentLikeMapper commentLikeMapper,
UserMapper userMapper, MangaMapper mangaMapper,
TeenGuard teenGuard) {
this.commentMapper = commentMapper;
this.commentLikeMapper = commentLikeMapper;
this.userMapper = userMapper;
this.mangaMapper = mangaMapper;
this.teenGuard = teenGuard;
}
@Override
public IPage<Map<String, Object>> pageQuery(CommentPageDTO dto) {
LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
if (dto.getMangaId() != null) {
wrapper.eq(Comment::getMangaId, dto.getMangaId());
}
if (dto.getStatus() != null) {
wrapper.eq(Comment::getStatus, dto.getStatus());
}
if (dto.getKeyword() != null && !dto.getKeyword().isEmpty()) {
wrapper.like(Comment::getContent, dto.getKeyword());
}
wrapper.orderByDesc(Comment::getCreateTime);
Page<Comment> page = commentMapper.selectPage(new Page<>(dto.getPageNum(), dto.getPageSize()), wrapper);
List<Map<String, Object>> records = page.getRecords().stream().map(c -> {
Map<String, Object> map = new HashMap<>();
map.put("id", c.getId());
map.put("mangaId", c.getMangaId());
map.put("userId", c.getUserId());
map.put("content", c.getContent());
map.put("likeCount", c.getLikeCount());
map.put("replyCount", c.getReplyCount());
map.put("status", c.getStatus());
map.put("createTime", c.getCreateTime());
User user = userMapper.selectById(c.getUserId());
map.put("nickname", user != null ? user.getNickname() : "已注销");
Manga manga = mangaMapper.selectById(c.getMangaId());
map.put("mangaTitle", manga != null ? manga.getTitle() : "已删除");
return map;
}).collect(Collectors.toList());
IPage<Map<String, Object>> result = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
result.setRecords(records);
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void toggleStatus(Long id, Integer status) {
Comment comment = commentMapper.selectById(id);
if (comment == null) {
throw new IllegalArgumentException("评论不存在");
}
comment.setStatus(status);
commentMapper.updateById(comment);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long id) {
commentMapper.deleteById(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Comment addComment(Long userId, Long mangaId, String content, Long parentId, Long replyUserId) {
if (content == null || content.trim().isEmpty() || content.length() > 500) {
throw new IllegalArgumentException("评论内容1-500字");
}
// 青少年模式:限制公开互动行为(发表评论、回复)
teenGuard.assertInteractionAllowed(userId);
Manga manga = mangaMapper.selectById(mangaId);
if (manga == null) {
throw new IllegalArgumentException("漫画不存在");
}
Comment comment = new Comment();
comment.setMangaId(mangaId);
comment.setUserId(userId);
comment.setContent(content.trim());
comment.setParentId(parentId);
comment.setReplyUserId(replyUserId);
comment.setLikeCount(0);
comment.setReplyCount(0);
comment.setStatus(1); // 正常
commentMapper.insert(comment);
// 如果是回复,更新父评论的回复数
if (parentId != null) {
Comment parent = commentMapper.selectById(parentId);
if (parent != null) {
parent.setReplyCount(parent.getReplyCount() == null ? 1 : parent.getReplyCount() + 1);
commentMapper.updateById(parent);
}
}
// 更新漫画评论数
manga.setCommentCount(manga.getCommentCount() == null ? 1 : manga.getCommentCount() + 1);
mangaMapper.updateById(manga);
return comment;
}
@Override
public IPage<Map<String, Object>> listComments(Long mangaId, int pageNum, int pageSize, Long currentUserId) {
// 查询主评论(parent_id IS NULL),状态正常
LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<Comment>()
.eq(Comment::getMangaId, mangaId)
.isNull(Comment::getParentId)
.eq(Comment::getStatus, 1)
.orderByDesc(Comment::getCreateTime);
Page<Comment> page = commentMapper.selectPage(new Page<>(pageNum, pageSize), wrapper);
List<Map<String, Object>> records = page.getRecords().stream().map(c -> {
Map<String, Object> map = buildCommentMap(c, currentUserId);
// 查询前3条回复
LambdaQueryWrapper<Comment> replyWrapper = new LambdaQueryWrapper<Comment>()
.eq(Comment::getParentId, c.getId())
.eq(Comment::getStatus, 1)
.orderByAsc(Comment::getCreateTime)
.last("LIMIT 3");
List<Comment> replies = commentMapper.selectList(replyWrapper);
map.put("replies", replies.stream().map(r -> buildCommentMap(r, currentUserId)).collect(Collectors.toList()));
return map;
}).collect(Collectors.toList());
IPage<Map<String, Object>> result = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
result.setRecords(records);
return result;
}
@Override
public List<Map<String, Object>> listTopComments(Long mangaId, int limit) {
LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<Comment>()
.eq(Comment::getMangaId, mangaId)
.isNull(Comment::getParentId)
.eq(Comment::getStatus, 1)
.orderByDesc(Comment::getLikeCount)
.last("LIMIT " + limit);
List<Comment> comments = commentMapper.selectList(wrapper);
return comments.stream().map(c -> buildCommentMap(c, null)).collect(Collectors.toList());
}
@Override
@Transactional(rollbackFor = Exception.class)
public Map<String, Object> toggleLike(Long userId, Long commentId) {
Comment comment = commentMapper.selectById(commentId);
if (comment == null) {
throw new IllegalArgumentException("评论不存在");
}
LambdaQueryWrapper<CommentLike> wrapper = new LambdaQueryWrapper<CommentLike>()
.eq(CommentLike::getCommentId, commentId)
.eq(CommentLike::getUserId, userId);
CommentLike like = commentLikeMapper.selectOne(wrapper);
boolean isLiked;
if (like != null) {
// 取消点赞
commentLikeMapper.delete(wrapper);
comment.setLikeCount(Math.max(0, (comment.getLikeCount() == null ? 0 : comment.getLikeCount()) - 1));
isLiked = false;
} else {
// 点赞
like = new CommentLike();
like.setCommentId(commentId);
like.setUserId(userId);
commentLikeMapper.insert(like);
comment.setLikeCount((comment.getLikeCount() == null ? 0 : comment.getLikeCount()) + 1);
isLiked = true;
}
commentMapper.updateById(comment);
Map<String, Object> result = new HashMap<>();
result.put("isLiked", isLiked);
result.put("likeCount", comment.getLikeCount());
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteMyComment(Long userId, Long commentId) {
Comment comment = commentMapper.selectById(commentId);
if (comment == null) {
throw new IllegalArgumentException("评论不存在");
}
if (!comment.getUserId().equals(userId)) {
throw new IllegalArgumentException("只能删除自己的评论");
}
commentMapper.deleteById(commentId);
// 更新漫画评论数
Manga manga = mangaMapper.selectById(comment.getMangaId());
if (manga != null) {
manga.setCommentCount(Math.max(0, (manga.getCommentCount() == null ? 0 : manga.getCommentCount()) - 1));
mangaMapper.updateById(manga);
}
}
@Override
public IPage<Map<String, Object>> listReplies(Long commentId, int pageNum, int pageSize, Long currentUserId) {
LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<Comment>()
.eq(Comment::getParentId, commentId)
.eq(Comment::getStatus, 1)
.orderByAsc(Comment::getCreateTime);
Page<Comment> page = commentMapper.selectPage(new Page<>(pageNum, pageSize), wrapper);
IPage<Map<String, Object>> result = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
result.setRecords(page.getRecords().stream().map(r -> buildCommentMap(r, currentUserId)).collect(Collectors.toList()));
return result;
}
@Override
public IPage<Map<String, Object>> listMyComments(Long userId, int pageNum, int pageSize) {
LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<Comment>()
.eq(Comment::getUserId, userId)
.orderByDesc(Comment::getCreateTime);
Page<Comment> page = commentMapper.selectPage(new Page<>(pageNum, pageSize), wrapper);
List<Map<String, Object>> records = page.getRecords().stream().map(c -> {
Map<String, Object> map = new HashMap<>();
map.put("id", c.getId());
map.put("content", c.getContent());
map.put("likeCount", c.getLikeCount());
map.put("replyCount", c.getReplyCount());
map.put("status", c.getStatus());
map.put("createTime", c.getCreateTime());
Manga manga = mangaMapper.selectById(c.getMangaId());
if (manga != null) {
map.put("mangaId", manga.getId());
map.put("mangaTitle", manga.getTitle());
map.put("mangaCover", manga.getCover());
} else {
map.put("mangaId", c.getMangaId());
map.put("mangaTitle", "已删除");
map.put("mangaCover", "");
}
return map;
}).collect(Collectors.toList());
IPage<Map<String, Object>> result = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
result.setRecords(records);
return result;
}
/** 构建评论的Map表示 */
private Map<String, Object> buildCommentMap(Comment comment, Long currentUserId) {
Map<String, Object> map = new HashMap<>();
map.put("id", comment.getId());
map.put("content", comment.getContent());
map.put("likeCount", comment.getLikeCount());
map.put("replyCount", comment.getReplyCount());
map.put("createTime", comment.getCreateTime());
map.put("parentId", comment.getParentId());
map.put("replyUserId", comment.getReplyUserId());
// 返回当前登录用户ID,前端据此判断「删除/举报」按钮显隐
map.put("currentUserId", currentUserId);
User user = userMapper.selectById(comment.getUserId());
map.put("userId", comment.getUserId());
map.put("userInfo", Map.of(
"nickname", user != null ? user.getNickname() : "已注销",
"avatar", user != null && user.getAvatar() != null ? user.getAvatar() : ""
));
if (comment.getReplyUserId() != null) {
User replyUser = userMapper.selectById(comment.getReplyUserId());
map.put("replyUserInfo", Map.of(
"nickname", replyUser != null ? replyUser.getNickname() : "已注销"
));
}
// 是否点赞
if (currentUserId != null) {
LambdaQueryWrapper<CommentLike> likeWrapper = new LambdaQueryWrapper<CommentLike>()
.eq(CommentLike::getCommentId, comment.getId())
.eq(CommentLike::getUserId, currentUserId);
map.put("isLiked", commentLikeMapper.selectCount(likeWrapper) > 0);
} else {
map.put("isLiked", false);
}
return map;
}
}
|
|