|
|
@@ -12,7 +12,6 @@ import shop.alien.entity.result.R;
|
|
|
import shop.alien.entity.store.LifeLikeRecord;
|
|
|
import shop.alien.entity.store.OrderReview;
|
|
|
import shop.alien.entity.store.ReviewComment;
|
|
|
-import shop.alien.entity.store.dto.ReviewCommentDto;
|
|
|
import shop.alien.entity.store.dto.ReviewCommentRequestDto;
|
|
|
import shop.alien.entity.store.dto.ReviewReplyDto;
|
|
|
import shop.alien.entity.store.vo.ReviewCommentVo;
|
|
|
@@ -23,6 +22,7 @@ import shop.alien.mapper.ReviewCommentMapper;
|
|
|
|
|
|
import java.util.Date;
|
|
|
import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* 评价评论 服务实现类
|
|
|
@@ -48,49 +48,54 @@ public class ReviewCommentServiceImpl extends ServiceImpl<ReviewCommentMapper, R
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public R<ReviewComment> createComment(ReviewCommentDto commentDto) {
|
|
|
- log.info("ReviewCommentServiceImpl.createComment?commentDto={}", commentDto);
|
|
|
-
|
|
|
+ public R<ReviewComment> createComment(ReviewComment comment) {
|
|
|
+ log.info("ReviewCommentServiceImpl.createComment?comment={}", comment);
|
|
|
// 参数校验
|
|
|
- if (commentDto == null) {
|
|
|
+ if (comment == null) {
|
|
|
return R.fail("评论信息不能为空");
|
|
|
}
|
|
|
- if (commentDto.getReviewId() == null) {
|
|
|
+ if (comment.getReviewId() == null) {
|
|
|
return R.fail("评价ID不能为空");
|
|
|
}
|
|
|
- if (commentDto.getCommentContent() == null || commentDto.getCommentContent().trim().isEmpty()) {
|
|
|
+ if (comment.getCommentContent() == null || comment.getCommentContent().trim().isEmpty()) {
|
|
|
return R.fail("评论内容不能为空");
|
|
|
}
|
|
|
- Integer userId=commentDto.getUserId() ;
|
|
|
+ Integer userId = comment.getSendUserId();
|
|
|
if (userId == null) {
|
|
|
return R.fail("用户ID不能为空");
|
|
|
}
|
|
|
|
|
|
// 验证评价是否存在
|
|
|
- OrderReview review = orderReviewService.getById(commentDto.getReviewId());
|
|
|
+ OrderReview review = orderReviewService.getById(comment.getReviewId());
|
|
|
if (review == null || review.getDeleteFlag() == 1) {
|
|
|
return R.fail("评价不存在或已删除");
|
|
|
}
|
|
|
|
|
|
- // 创建评论
|
|
|
- ReviewComment comment = new ReviewComment();
|
|
|
- comment.setReviewId(commentDto.getReviewId());
|
|
|
- comment.setSendUserId(userId);
|
|
|
- // 接收用户ID为评价的创建者
|
|
|
- comment.setReceiveUserId(review.getUserId());
|
|
|
- comment.setCommentContent(commentDto.getCommentContent());
|
|
|
- comment.setLikeCount(0);
|
|
|
- comment.setReplyCount(0);
|
|
|
- comment.setHeadType(0); // 0:是首评
|
|
|
+ // 设置评论属性
|
|
|
+ // 接收用户ID为评价的创建者(如果未设置)
|
|
|
+ if (comment.getReceiveUserId() == null) {
|
|
|
+ comment.setReceiveUserId(review.getUserId());
|
|
|
+ }
|
|
|
+ // 设置默认值
|
|
|
+ if (comment.getLikeCount() == null) {
|
|
|
+ comment.setLikeCount(0);
|
|
|
+ }
|
|
|
+ if (comment.getReplyCount() == null) {
|
|
|
+ comment.setReplyCount(0);
|
|
|
+ }
|
|
|
+ if (comment.getHeadType() == null) {
|
|
|
+ comment.setHeadType(0); // 0:是首评
|
|
|
+ }
|
|
|
comment.setCreatedUserId(userId);
|
|
|
comment.setCreatedTime(new Date());
|
|
|
|
|
|
boolean success = this.save(comment);
|
|
|
if (success) {
|
|
|
- // 更新评价的评论数
|
|
|
+ // 更新评价的评论数(包括首评论和子评论)
|
|
|
review.setCommentCount((review.getCommentCount() == null ? 0 : review.getCommentCount()) + 1);
|
|
|
orderReviewService.updateById(review);
|
|
|
-
|
|
|
+ log.info("更新评价评论数成功,评价ID={}, 评论数={}", comment.getReviewId(), review.getCommentCount());
|
|
|
+
|
|
|
log.info("创建评论成功,评论ID={}", comment.getId());
|
|
|
return R.data(comment, "评论成功");
|
|
|
} else {
|
|
|
@@ -108,7 +113,7 @@ public class ReviewCommentServiceImpl extends ServiceImpl<ReviewCommentMapper, R
|
|
|
}
|
|
|
|
|
|
List<ReviewCommentVo> comments = reviewCommentMapper.getCommentListByReviewId(reviewId, currentUserId);
|
|
|
-
|
|
|
+
|
|
|
// 为每个首评加载回复列表
|
|
|
if (comments != null && !comments.isEmpty()) {
|
|
|
for (ReviewCommentVo comment : comments) {
|
|
|
@@ -116,65 +121,8 @@ public class ReviewCommentServiceImpl extends ServiceImpl<ReviewCommentMapper, R
|
|
|
comment.setReplies(replies);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- return R.data(comments);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public R<Boolean> deleteComment(ReviewCommentRequestDto requestDto) {
|
|
|
- log.info("ReviewCommentServiceImpl.deleteComment?requestDto={}", requestDto);
|
|
|
-
|
|
|
- Integer commentId = requestDto.getCommentId();
|
|
|
- Integer userId = requestDto.getUserId();
|
|
|
-
|
|
|
- if (commentId == null) {
|
|
|
- return R.fail("评论ID不能为空");
|
|
|
- }
|
|
|
- if (userId == null) {
|
|
|
- return R.fail("用户ID不能为空");
|
|
|
- }
|
|
|
-
|
|
|
- // 查询评论
|
|
|
- ReviewComment comment = this.getById(commentId);
|
|
|
- if (comment == null) {
|
|
|
- return R.fail("评论不存在");
|
|
|
- }
|
|
|
-
|
|
|
- // 验证是否为评论用户
|
|
|
- if (!comment.getSendUserId().equals(userId)) {
|
|
|
- return R.fail("只能删除自己的评论");
|
|
|
- }
|
|
|
-
|
|
|
- // 删除评论下的所有回复(逻辑删除)
|
|
|
- LambdaUpdateWrapper<ReviewComment> replyUpdateWrapper = new LambdaUpdateWrapper<>();
|
|
|
- replyUpdateWrapper.eq(ReviewComment::getHeadId, commentId)
|
|
|
- .eq(ReviewComment::getHeadType, 1)
|
|
|
- .eq(ReviewComment::getDeleteFlag, 0);
|
|
|
- replyUpdateWrapper.set(ReviewComment::getDeleteFlag, 1);
|
|
|
- replyUpdateWrapper.set(ReviewComment::getUpdatedUserId, userId);
|
|
|
- replyUpdateWrapper.set(ReviewComment::getUpdatedTime, new Date());
|
|
|
- this.update(replyUpdateWrapper);
|
|
|
|
|
|
- // 删除评论(逻辑删除)
|
|
|
- comment.setDeleteFlag(1);
|
|
|
- comment.setUpdatedUserId(userId);
|
|
|
- comment.setUpdatedTime(new Date());
|
|
|
- boolean success = this.updateById(comment);
|
|
|
-
|
|
|
- if (success) {
|
|
|
- // 更新评价的评论数
|
|
|
- OrderReview review = orderReviewService.getById(comment.getReviewId());
|
|
|
- if (review != null) {
|
|
|
- review.setCommentCount((review.getCommentCount() == null ? 0 : review.getCommentCount()) - 1);
|
|
|
- orderReviewService.updateById(review);
|
|
|
- }
|
|
|
-
|
|
|
- log.info("删除评论成功,评论ID={}", commentId);
|
|
|
- return R.data(true, "删除成功");
|
|
|
- } else {
|
|
|
- log.error("删除评论失败,评论ID={}", commentId);
|
|
|
- return R.fail("删除评论失败");
|
|
|
- }
|
|
|
+ return R.data(comments);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -256,17 +204,13 @@ public class ReviewCommentServiceImpl extends ServiceImpl<ReviewCommentMapper, R
|
|
|
if (!CollectionUtils.isEmpty(records)) {
|
|
|
// 删除点赞记录(逻辑删除)
|
|
|
for (LifeLikeRecord record : records) {
|
|
|
- record.setDeleteFlag(1);
|
|
|
- record.setUpdatedUserId(userId);
|
|
|
- record.setUpdatedTime(new Date());
|
|
|
- lifeLikeRecordMapper.updateById(record);
|
|
|
+ lifeLikeRecordMapper.deleteById(record.getId());
|
|
|
}
|
|
|
|
|
|
- // 更新评论点赞数
|
|
|
+ // 更新评论点赞数(移除 gt 条件,确保即使为 0 也能正确更新)
|
|
|
LambdaUpdateWrapper<ReviewComment> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
updateWrapper.eq(ReviewComment::getId, commentId);
|
|
|
- updateWrapper.gt(ReviewComment::getLikeCount, 0);
|
|
|
- updateWrapper.setSql("like_count = like_count - 1");
|
|
|
+ updateWrapper.setSql("like_count = GREATEST(0, like_count - 1)");
|
|
|
int result = reviewCommentMapper.update(null, updateWrapper);
|
|
|
|
|
|
if (result > 0) {
|
|
|
@@ -326,7 +270,15 @@ public class ReviewCommentServiceImpl extends ServiceImpl<ReviewCommentMapper, R
|
|
|
// 更新首评的回复数
|
|
|
headComment.setReplyCount((headComment.getReplyCount() == null ? 0 : headComment.getReplyCount()) + 1);
|
|
|
this.updateById(headComment);
|
|
|
-
|
|
|
+
|
|
|
+ // 更新评价的评论数(包括子评论)
|
|
|
+ OrderReview review = orderReviewService.getById(reply.getReviewId());
|
|
|
+ if (review != null) {
|
|
|
+ review.setCommentCount((review.getCommentCount() == null ? 0 : review.getCommentCount()) + 1);
|
|
|
+ orderReviewService.updateById(review);
|
|
|
+ log.info("更新评价评论数成功,评价ID={}, 评论数={}", reply.getReviewId(), review.getCommentCount());
|
|
|
+ }
|
|
|
+
|
|
|
log.info("创建回复成功,回复ID={}", reply.getId());
|
|
|
return R.data(reply, "回复成功");
|
|
|
} else {
|
|
|
@@ -373,19 +325,27 @@ public class ReviewCommentServiceImpl extends ServiceImpl<ReviewCommentMapper, R
|
|
|
}
|
|
|
|
|
|
// 删除回复(逻辑删除)
|
|
|
- reply.setDeleteFlag(1);
|
|
|
- reply.setUpdatedUserId(userId);
|
|
|
- reply.setUpdatedTime(new Date());
|
|
|
- boolean success = this.updateById(reply);
|
|
|
+ boolean success = this.removeById(reply.getId());
|
|
|
|
|
|
if (success) {
|
|
|
// 更新首评的回复数
|
|
|
ReviewComment headComment = this.getById(reply.getHeadId());
|
|
|
if (headComment != null) {
|
|
|
headComment.setReplyCount((headComment.getReplyCount() == null ? 0 : headComment.getReplyCount()) - 1);
|
|
|
+ headComment.setReplyCount(Math.max(0, headComment.getReplyCount())); // 确保回复数不为负数
|
|
|
this.updateById(headComment);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ // 更新评价的评论数(包括子评论)
|
|
|
+ OrderReview review = orderReviewService.getById(reply.getReviewId());
|
|
|
+ if (review != null) {
|
|
|
+ Integer currentCount = review.getCommentCount() == null ? 0 : review.getCommentCount();
|
|
|
+ review.setCommentCount(Math.max(0, currentCount - 1)); // 确保评论数不为负数
|
|
|
+ orderReviewService.updateById(review);
|
|
|
+ log.info("更新评价评论数成功,评价ID={}, 原评论数={}, 新评论数={}",
|
|
|
+ reply.getReviewId(), currentCount, review.getCommentCount());
|
|
|
+ }
|
|
|
+
|
|
|
log.info("删除回复成功,回复ID={}", replyId);
|
|
|
return R.data(true, "删除成功");
|
|
|
} else {
|
|
|
@@ -394,105 +354,81 @@ public class ReviewCommentServiceImpl extends ServiceImpl<ReviewCommentMapper, R
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public R<Boolean> likeReply(Integer replyId, Integer userId) {
|
|
|
- log.info("ReviewCommentServiceImpl.likeReply?replyId={}, userId={}", replyId, userId);
|
|
|
|
|
|
- if (replyId == null) {
|
|
|
- return R.fail("回复ID不能为空");
|
|
|
- }
|
|
|
- if (userId == null) {
|
|
|
- return R.fail("用户ID不能为空");
|
|
|
+ @Override
|
|
|
+ public R<Boolean> deleteReviewComment(ReviewComment reviewComment) {
|
|
|
+ Integer id = reviewComment.getId();
|
|
|
+ Integer userId = reviewComment.getUserId();
|
|
|
+ log.info("ReviewCommentServiceImpl.deleteReviewComment?id={}, userId={}", id, userId);
|
|
|
+ if (id == null) {
|
|
|
+ return R.fail("评论ID不能为空");
|
|
|
}
|
|
|
|
|
|
- // 验证回复是否存在
|
|
|
- ReviewComment reply = this.getById(replyId);
|
|
|
- if (reply == null || reply.getDeleteFlag() == 1) {
|
|
|
- return R.fail("回复不存在或已删除");
|
|
|
- }
|
|
|
- if (reply.getHeadType() != 1) {
|
|
|
- return R.fail("该记录不是回复");
|
|
|
+ // 查询评论
|
|
|
+ ReviewComment comment = this.getById(id);
|
|
|
+ if (comment == null) {
|
|
|
+ return R.fail("评论不存在");
|
|
|
}
|
|
|
|
|
|
- // 检查是否已点赞
|
|
|
- LambdaQueryWrapper<LifeLikeRecord> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(LifeLikeRecord::getType, "8")
|
|
|
- .eq(LifeLikeRecord::getDianzanId, String.valueOf(userId))
|
|
|
- .eq(LifeLikeRecord::getHuifuId, String.valueOf(replyId))
|
|
|
- .eq(LifeLikeRecord::getDeleteFlag, 0);
|
|
|
- List<LifeLikeRecord> records = lifeLikeRecordMapper.selectList(queryWrapper);
|
|
|
-
|
|
|
- if (CollectionUtils.isEmpty(records)) {
|
|
|
- // 插入点赞记录
|
|
|
- LifeLikeRecord likeRecord = new LifeLikeRecord();
|
|
|
- likeRecord.setDianzanId(String.valueOf(userId));
|
|
|
- likeRecord.setHuifuId(String.valueOf(replyId));
|
|
|
- likeRecord.setType("8");
|
|
|
- likeRecord.setCreatedTime(new Date());
|
|
|
- likeRecord.setCreatedUserId(userId);
|
|
|
- lifeLikeRecordMapper.insert(likeRecord);
|
|
|
-
|
|
|
- // 更新回复点赞数
|
|
|
- LambdaUpdateWrapper<ReviewComment> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
- updateWrapper.eq(ReviewComment::getId, replyId);
|
|
|
- updateWrapper.setSql("like_count = like_count + 1");
|
|
|
- int result = reviewCommentMapper.update(null, updateWrapper);
|
|
|
-
|
|
|
- if (result > 0) {
|
|
|
- log.info("点赞回复成功,回复ID={}", replyId);
|
|
|
- return R.data(true, "点赞成功");
|
|
|
- } else {
|
|
|
- return R.fail("点赞失败");
|
|
|
+ // 当userId有值时,验证是否为评论用户(只能删除自己的评论)
|
|
|
+ if (userId != null) {
|
|
|
+ if (!comment.getSendUserId().equals(userId)) {
|
|
|
+ return R.fail("只能删除自己的评论");
|
|
|
}
|
|
|
- } else {
|
|
|
- return R.data(true, "已点赞");
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public R<Boolean> cancelLikeReply(Integer replyId, Integer userId) {
|
|
|
- log.info("ReviewCommentServiceImpl.cancelLikeReply?replyId={}, userId={}", replyId, userId);
|
|
|
|
|
|
- if (replyId == null) {
|
|
|
- return R.fail("回复ID不能为空");
|
|
|
- }
|
|
|
- if (userId == null) {
|
|
|
- return R.fail("用户ID不能为空");
|
|
|
+ // 计算需要减少的评论数
|
|
|
+ int commentCountToReduce = 1; // 至少减少1(当前评论本身)
|
|
|
+
|
|
|
+ // 判断是否为首评论(headType == 0 表示是首评论)
|
|
|
+ if (comment.getHeadType() != null && comment.getHeadType() == 0) {
|
|
|
+ // 如果是首评论,需要先删除所有子评论
|
|
|
+ LambdaQueryWrapper<ReviewComment> childQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ childQueryWrapper.eq(ReviewComment::getHeadId, id)
|
|
|
+ .eq(ReviewComment::getHeadType, 1)
|
|
|
+ .eq(ReviewComment::getDeleteFlag, 0);
|
|
|
+ List<ReviewComment> childComments = this.list(childQueryWrapper);
|
|
|
+
|
|
|
+ if (!CollectionUtils.isEmpty(childComments)) {
|
|
|
+ // 批量删除子评论
|
|
|
+ List<Integer> childIds = childComments.stream()
|
|
|
+ .map(ReviewComment::getId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ boolean deleteChildrenResult = this.removeByIds(childIds);
|
|
|
+ if (!deleteChildrenResult) {
|
|
|
+ log.warn("删除子评论失败,首评论ID={}, 子评论数量={}", id, childIds.size());
|
|
|
+ return R.fail("删除子评论失败");
|
|
|
+ }
|
|
|
+ // 增加需要减少的评论数(包括所有子评论)
|
|
|
+ commentCountToReduce += childComments.size();
|
|
|
+ log.info("删除首评论下的子评论成功,首评论ID={}, 子评论数量={}", id, childIds.size());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- // 查询点赞记录
|
|
|
- LambdaQueryWrapper<LifeLikeRecord> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(LifeLikeRecord::getType, "8")
|
|
|
- .eq(LifeLikeRecord::getDianzanId, String.valueOf(userId))
|
|
|
- .eq(LifeLikeRecord::getHuifuId, String.valueOf(replyId))
|
|
|
- .eq(LifeLikeRecord::getDeleteFlag, 0);
|
|
|
- List<LifeLikeRecord> records = lifeLikeRecordMapper.selectList(queryWrapper);
|
|
|
-
|
|
|
- if (!CollectionUtils.isEmpty(records)) {
|
|
|
- // 删除点赞记录(逻辑删除)
|
|
|
- for (LifeLikeRecord record : records) {
|
|
|
- record.setDeleteFlag(1);
|
|
|
- record.setUpdatedUserId(userId);
|
|
|
- record.setUpdatedTime(new Date());
|
|
|
- lifeLikeRecordMapper.updateById(record);
|
|
|
+ // 删除评论本身(物理删除)
|
|
|
+ boolean result = this.removeById(id);
|
|
|
+ if (result) {
|
|
|
+ // 更新评价的评论数(包括首评论和子评论)
|
|
|
+ OrderReview review = orderReviewService.getById(comment.getReviewId());
|
|
|
+ if (review != null) {
|
|
|
+ Integer currentCount = review.getCommentCount() == null ? 0 : review.getCommentCount();
|
|
|
+ review.setCommentCount(Math.max(0, currentCount - commentCountToReduce)); // 确保评论数不为负数
|
|
|
+ orderReviewService.updateById(review);
|
|
|
+ log.info("更新评价评论数成功,评价ID={}, 原评论数={}, 减少数量={}, 新评论数={}",
|
|
|
+ comment.getReviewId(), currentCount, commentCountToReduce, review.getCommentCount());
|
|
|
}
|
|
|
|
|
|
- // 更新回复点赞数
|
|
|
- LambdaUpdateWrapper<ReviewComment> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
- updateWrapper.eq(ReviewComment::getId, replyId);
|
|
|
- updateWrapper.gt(ReviewComment::getLikeCount, 0);
|
|
|
- updateWrapper.setSql("like_count = like_count - 1");
|
|
|
- int result = reviewCommentMapper.update(null, updateWrapper);
|
|
|
-
|
|
|
- if (result > 0) {
|
|
|
- log.info("取消点赞回复成功,回复ID={}", replyId);
|
|
|
- return R.data(true, "取消点赞成功");
|
|
|
+ if (userId != null) {
|
|
|
+ log.info("删除评论成功,评论ID={}, userId={}, 是否首评论={}, 减少评论数={}", id, userId,
|
|
|
+ comment.getHeadType() != null && comment.getHeadType() == 0, commentCountToReduce);
|
|
|
} else {
|
|
|
- return R.fail("取消点赞失败");
|
|
|
+ log.info("管理员删除评论成功,评论ID={}, 是否首评论={}, 减少评论数={}", id,
|
|
|
+ comment.getHeadType() != null && comment.getHeadType() == 0, commentCountToReduce);
|
|
|
}
|
|
|
- } else {
|
|
|
- return R.data(true, "未点赞");
|
|
|
+ return R.success("删除成功");
|
|
|
}
|
|
|
+ log.warn("删除评论失败,评论ID={}, userId={}", id, userId);
|
|
|
+ return R.fail("删除失败");
|
|
|
}
|
|
|
}
|
|
|
|