Ver Fonte

律师评分评论一大堆代码

LuTong há 3 semanas atrás
pai
commit
cb9304f80a

+ 34 - 2
alien-entity/src/main/java/shop/alien/entity/store/LawyerUser.java

@@ -8,6 +8,9 @@ import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.temporal.ChronoUnit;
 import java.util.Date;
 import java.util.List;
 
@@ -141,8 +144,8 @@ public class LawyerUser extends Model<LawyerUser> {
     @TableField("law_firm")
     private String lawFirm;
 
-    @ApiModelProperty(value = "执业年限")
-    @TableField("practice_years")
+    @ApiModelProperty(value = "执业年限(根据执业开始日期自动计算)")
+    @TableField(exist = false)
     private Integer practiceYears;
 
     @ApiModelProperty(value = "执业开始日期")
@@ -150,6 +153,31 @@ public class LawyerUser extends Model<LawyerUser> {
     @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private Date practiceStartDate;
 
+    /**
+     * 获取执业年限(根据执业开始日期自动计算)
+     * 返回当前时间减去执业开始时间的年数
+     *
+     * @return 执业年限(年)
+     */
+    public Integer getPracticeYears() {
+        if (practiceStartDate == null) {
+            return null;
+        }
+        try {
+            // 将 Date 转换为 LocalDate
+            LocalDate startDate = practiceStartDate.toInstant()
+                    .atZone(ZoneId.systemDefault())
+                    .toLocalDate();
+            LocalDate currentDate = LocalDate.now();
+            
+            // 计算年数差
+            long years = ChronoUnit.YEARS.between(startDate, currentDate);
+            return (int) Math.max(0, years); // 确保不为负数
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
     @ApiModelProperty(value = "专业领域,多个用逗号分隔")
     @TableField("specialty_fields")
     private String specialtyFields;
@@ -305,5 +333,9 @@ public class LawyerUser extends Model<LawyerUser> {
     @TableField(exist = false)
     private String moneyStr;
 
+    @ApiModelProperty(value = "评价数(只统计评价,不包含评论)")
+    @TableField(exist = false)
+    private Integer reviewCount;
+
 }
 

+ 4 - 0
alien-entity/src/main/java/shop/alien/entity/store/ReviewComment.java

@@ -80,5 +80,9 @@ public class ReviewComment {
     @ApiModelProperty(value = "修改人ID")
     @TableField("updated_user_id")
     private Integer updatedUserId;
+
+    @ApiModelProperty(value = "登陆人")
+    @TableField(exist = false)
+    private Integer userId;
 }
 

+ 4 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/OrderReviewVo.java

@@ -66,6 +66,10 @@ public class OrderReviewVo {
     @ApiModelProperty(value = "评价图片列表")
     private List<String> reviewImages;
 
+    @ApiModelProperty(value = "评价图片JSON字符串(内部使用,不对外暴露)")
+    @com.fasterxml.jackson.annotation.JsonIgnore
+    private String reviewImagesJson;
+
     @ApiModelProperty(value = "是否匿名评价,0:否,1:是")
     private Integer isAnonymous;
 

+ 5 - 2
alien-entity/src/main/java/shop/alien/entity/store/vo/ReviewCommentVo.java

@@ -30,12 +30,15 @@ public class ReviewCommentVo {
     @ApiModelProperty(value = "接收用户ID")
     private Integer receiveUserId;
 
-    @ApiModelProperty(value = "评论用户名称")
-    private String userName;
+    @ApiModelProperty(value = "评论用户名称(发送者)")
+    private String sendUserName;
 
     @ApiModelProperty(value = "评论用户头像")
     private String userAvatar;
 
+    @ApiModelProperty(value = "接收用户名称")
+    private String receiveUserName;
+
     @ApiModelProperty(value = "评论内容")
     private String commentContent;
 

+ 8 - 0
alien-entity/src/main/java/shop/alien/mapper/OrderReviewMapper.java

@@ -64,5 +64,13 @@ public interface OrderReviewMapper extends BaseMapper<OrderReview> {
             IPage<PendingReviewVo> page,
             @Param("userId") Integer userId
     );
+
+    /**
+     * 计算律师的平均评分(overallRating的平均值)
+     *
+     * @param lawyerUserId 律师用户ID
+     * @return 平均评分(1-5星)
+     */
+    Double getAverageRatingByLawyerUserId(@Param("lawyerUserId") Integer lawyerUserId);
 }
 

+ 9 - 1
alien-entity/src/main/java/shop/alien/mapper/ReviewCommentMapper.java

@@ -27,7 +27,7 @@ public interface ReviewCommentMapper extends BaseMapper<ReviewComment> {
     List<ReviewCommentVo> getCommentListByReviewId(@Param("reviewId") Integer reviewId, @Param("currentUserId") Integer currentUserId);
 
     /**
-     * 根据评价ID查询评论数量
+     * 根据评价ID查询评论数量(只统计首评论)
      *
      * @param reviewId 评价ID
      * @return 评论数量
@@ -35,6 +35,14 @@ public interface ReviewCommentMapper extends BaseMapper<ReviewComment> {
     Integer getCommentCountByReviewId(@Param("reviewId") Integer reviewId);
 
     /**
+     * 根据评价ID查询总评论数量(包括首评论和子评论)
+     *
+     * @param reviewId 评价ID
+     * @return 总评论数量
+     */
+    Integer getTotalCommentCountByReviewId(@Param("reviewId") Integer reviewId);
+
+    /**
      * 根据首评ID查询回复列表(包含用户信息)
      *
      * @param headId 首评ID

+ 18 - 1
alien-entity/src/main/resources/mapper/OrderReviewMapper.xml

@@ -19,6 +19,7 @@
         <result column="response_time_rating" property="responseTimeRating" />
         <result column="professional_ability_rating" property="professionalAbilityRating" />
         <result column="review_content" property="reviewContent" />
+        <result column="review_images" property="reviewImagesJson" />
         <result column="is_anonymous" property="isAnonymous" />
         <result column="like_count" property="likeCount" />
         <result column="comment_count" property="commentCount" />
@@ -149,8 +150,15 @@
             orv.response_time_rating,
             orv.professional_ability_rating,
             orv.review_content,
+            orv.review_images,
             orv.is_anonymous,
-            orv.like_count,
+            COALESCE((
+                SELECT COUNT(1) 
+                FROM life_like_record llr_count 
+                WHERE CONVERT(llr_count.huifu_id, CHAR) = CONVERT(orv.id, CHAR)
+                    AND llr_count.type = '7'
+                    AND llr_count.delete_flag = 0
+            ), 0) AS like_count,
             orv.comment_count,
             CASE 
                 WHEN #{currentUserId} IS NOT NULL AND llr.id IS NOT NULL THEN 1
@@ -207,5 +215,14 @@
         ORDER BY lco.end_time DESC
     </select>
 
+    <!-- 计算律师的平均评分(overallRating的平均值) -->
+    <select id="getAverageRatingByLawyerUserId" resultType="java.lang.Double">
+        SELECT AVG(overall_rating)
+        FROM lawyer_order_review
+        WHERE lawyer_user_id = #{lawyerUserId}
+        AND delete_flag = 0
+        AND overall_rating IS NOT NULL
+    </select>
+
 </mapper>
 

+ 14 - 2
alien-entity/src/main/resources/mapper/ReviewCommentMapper.xml

@@ -8,8 +8,9 @@
         <result column="review_id" property="reviewId" />
         <result column="send_user_id" property="sendUserId" />
         <result column="receive_user_id" property="receiveUserId" />
-        <result column="user_name" property="userName" />
+        <result column="user_name" property="sendUserName" />
         <result column="user_avatar" property="userAvatar" />
+        <result column="receive_user_name" property="receiveUserName" />
         <result column="comment_content" property="commentContent" />
         <result column="like_count" property="likeCount" />
         <result column="reply_count" property="replyCount" />
@@ -28,6 +29,7 @@
             rc.receive_user_id,
             lu.user_name AS user_name,
             lu.user_image AS user_avatar,
+            lu2.user_name AS receive_user_name,
             rc.comment_content,
             rc.like_count,
             rc.reply_count,
@@ -40,6 +42,7 @@
             rc.created_time
         FROM lawyer_review_comment rc
         LEFT JOIN life_user lu ON lu.id = rc.send_user_id AND lu.delete_flag = 0
+        LEFT JOIN life_user lu2 ON lu2.id = rc.receive_user_id AND lu2.delete_flag = 0
         LEFT JOIN life_like_record llr ON CONVERT(llr.huifu_id, CHAR) = CONVERT(rc.id, CHAR)
             AND llr.type = '8' 
             AND CONVERT(llr.dianzan_id, CHAR) = CONVERT(#{currentUserId}, CHAR)
@@ -59,6 +62,7 @@
             rc.receive_user_id,
             lu.user_name AS user_name,
             lu.user_image AS user_avatar,
+            lu2.user_name AS receive_user_name,
             rc.comment_content,
             rc.like_count,
             rc.reply_count,
@@ -82,7 +86,7 @@
         ORDER BY rc.created_time ASC
     </select>
 
-    <!-- 根据评价ID查询评论数量 -->
+    <!-- 根据评价ID查询评论数量(只统计首评论) -->
     <select id="getCommentCountByReviewId" resultType="java.lang.Integer">
         SELECT COUNT(*)
         FROM lawyer_review_comment
@@ -91,5 +95,13 @@
         AND head_type = 0
     </select>
 
+    <!-- 根据评价ID查询总评论数量(包括首评论和子评论) -->
+    <select id="getTotalCommentCountByReviewId" resultType="java.lang.Integer">
+        SELECT COUNT(*)
+        FROM lawyer_review_comment
+        WHERE delete_flag = 0
+        AND review_id = #{reviewId}
+    </select>
+
 </mapper>
 

+ 0 - 8
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerLegalProblemScenarioController.java

@@ -1,13 +1,11 @@
 package shop.alien.lawyer.controller;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import io.swagger.annotations.*;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.result.R;
-import shop.alien.entity.store.LawyerImg;
 import shop.alien.entity.store.LawyerLegalProblemScenario;
 import shop.alien.lawyer.service.LawyerLegalProblemScenarioService;
 import shop.alien.mapper.LawyerImgMapper;
@@ -92,12 +90,6 @@ public class LawyerLegalProblemScenarioController {
                 .build()
                 .list(lawyerLegalProblemScenarioService);
 
-        for (LawyerLegalProblemScenario item : list) {
-            Integer id = item.getId();
-            LawyerImg a = lawyerImgMapper.getLawyerImgById(id);
-            item.setImgUrl(ObjectUtils.isNotEmpty(a) ? a.getImgUrl() : "");
-        }
-
         return R.data(list);
     }
 

+ 59 - 58
alien-lawyer/src/main/java/shop/alien/lawyer/controller/OrderReviewController.java

@@ -41,6 +41,60 @@ public class OrderReviewController {
         return orderReviewService.createReview(reviewDto);
     }
 
+    @ApiOperation("获取评价详情(包含评论和回复)")
+    @ApiOperationSupport(order = 3)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "reviewId", value = "评价ID", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "currentUserId", value = "当前用户ID(用于判断是否已点赞)", dataType = "int", paramType = "query")
+    })
+    @GetMapping("/detail/reviewId")
+    public R<OrderReviewDetailVo> getReviewDetail(
+            @RequestParam Integer reviewId,
+            @RequestParam(required = false) Integer currentUserId) {
+        log.info("OrderReviewController.getReviewDetail?reviewId={}, currentUserId={}", reviewId, currentUserId);
+        if (reviewId == null) {
+            return R.fail("评价ID不能为空");
+        }
+        return orderReviewService.getReviewDetail(reviewId, currentUserId);
+    }
+
+    @ApiOperation("点赞评价")
+    @ApiOperationSupport(order = 8)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "reviewId", value = "评价ID", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "int", paramType = "query", required = true)
+    })
+    @PostMapping("/like")
+    public R<Boolean> likeReview(@RequestBody OrderReview orderReview) {
+        Integer reviewId = orderReview.getId();
+        Integer userId = orderReview.getUserId();
+        log.info("OrderReviewController.likeReview?reviewId={}, userId={}", reviewId, userId);
+        if (userId == null) {
+            return R.fail("用户未登录");
+        }
+        if (reviewId == null) {
+            return R.fail("评价ID不能为空");
+        }
+        return orderReviewService.likeReview(reviewId, userId);
+    }
+
+    @ApiOperation("取消点赞评价")
+    @ApiOperationSupport(order = 9)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "reviewId", value = "评价ID", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "int", paramType = "query", required = true)
+    })
+    @PostMapping("/cancelLike")
+    public R<Boolean> cancelLikeReview(@RequestBody OrderReview orderReview) {
+        Integer reviewId = orderReview.getId();
+        Integer userId = orderReview.getUserId();
+        log.info("OrderReviewController.cancelLikeReview?reviewId={}, userId={}", reviewId, userId);
+        if (userId == null) {
+            return R.fail("用户未登录");
+        }
+        return orderReviewService.cancelLikeReview(reviewId, userId);
+    }
+
     @ApiOperation("分页查询评价列表")
     @ApiOperationSupport(order = 2)
     @ApiImplicitParams({
@@ -64,33 +118,16 @@ public class OrderReviewController {
         return orderReviewService.getReviewList(page, size, orderId, lawyerUserId, userId, currentUserId);
     }
 
-    @ApiOperation("获取评价详情(包含评论和回复)")
-    @ApiOperationSupport(order = 3)
-    @ApiImplicitParams({
-            @ApiImplicitParam(name = "reviewId", value = "评价ID", dataType = "int", paramType = "query", required = true),
-            @ApiImplicitParam(name = "currentUserId", value = "当前用户ID(用于判断是否已点赞)", dataType = "int", paramType = "query")
-    })
-    @GetMapping("/detail/reviewId")
-    public R<OrderReviewDetailVo> getReviewDetail(
-            @RequestParam Integer reviewId,
-            @RequestParam(required = false) Integer currentUserId) {
-        log.info("OrderReviewController.getReviewDetail?reviewId={}, currentUserId={}", reviewId, currentUserId);
-        return orderReviewService.getReviewDetail(reviewId, currentUserId);
-    }
-
     @ApiOperation("删除评价(删除评价时,会级联删除该评价下的所有评论和回复)")
     @ApiOperationSupport(order = 4)
     @ApiImplicitParams({
-    @ApiImplicitParam(name = "reviewId", value = "评价ID", dataType = "int", paramType = "query", required = true),
-    @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "int", paramType = "query", required = true)
-             })
+            @ApiImplicitParam(name = "reviewId", value = "评价ID", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "userId", value = "用户ID(可选,有值时只能删除自己的评价,为空时允许删除任何评价)", dataType = "int", paramType = "query", required = false)
+    })
     @PostMapping("/delete/reviewId")
-    public R<Boolean> deleteReview( @RequestParam Integer reviewId,
-                                    @RequestParam Integer userId) {
+    public R<Boolean> deleteReview(@RequestParam Integer reviewId,
+                                   @RequestParam(required = false) Integer userId) {
         log.info("OrderReviewController.deleteReview?reviewId={}, userId={}", reviewId, userId);
-        if (userId == null) {
-            return R.fail("用户未登录");
-        }
         return orderReviewService.deleteReview(reviewId, userId);
     }
 
@@ -109,8 +146,6 @@ public class OrderReviewController {
     }
 
 
-
-
     @ApiOperation("分页查询我的评价列表")
     @ApiOperationSupport(order = 6)
     @ApiImplicitParams({
@@ -150,39 +185,5 @@ public class OrderReviewController {
         }
         return orderReviewService.getMyReviewList(page, size, userId, currentUserId);
     }
-
-    @ApiOperation("点赞评价")
-    @ApiOperationSupport(order = 8)
-    @ApiImplicitParams({
-            @ApiImplicitParam(name = "reviewId", value = "评价ID", dataType = "int", paramType = "query", required = true),
-            @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "int", paramType = "query", required = true)
-    })
-    @PostMapping("/like")
-    public R<Boolean> likeReview(
-            @RequestParam Integer reviewId,
-            @RequestParam Integer userId) {
-        log.info("OrderReviewController.likeReview?reviewId={}, userId={}", reviewId, userId);
-        if (userId == null) {
-            return R.fail("用户未登录");
-        }
-        return orderReviewService.likeReview(reviewId, userId);
-    }
-
-    @ApiOperation("取消点赞评价")
-    @ApiOperationSupport(order = 9)
-    @ApiImplicitParams({
-            @ApiImplicitParam(name = "reviewId", value = "评价ID", dataType = "int", paramType = "query", required = true),
-            @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "int", paramType = "query", required = true)
-    })
-    @PostMapping("/cancelLike")
-    public R<Boolean> cancelLikeReview(
-            @RequestParam Integer reviewId,
-            @RequestParam Integer userId) {
-        log.info("OrderReviewController.cancelLikeReview?reviewId={}, userId={}", reviewId, userId);
-        if (userId == null) {
-            return R.fail("用户未登录");
-        }
-        return orderReviewService.cancelLikeReview(reviewId, userId);
-    }
 }
 

+ 35 - 57
alien-lawyer/src/main/java/shop/alien/lawyer/controller/ReviewCommentController.java

@@ -6,13 +6,10 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.result.R;
 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;
-import shop.alien.entity.store.UserLoginInfo;
 import shop.alien.lawyer.service.ReviewCommentService;
-import shop.alien.util.common.TokenInfo;
 
 import java.util.List;
 
@@ -36,12 +33,12 @@ public class ReviewCommentController {
     @ApiOperation("创建评论(其他用户对评价的评论)")
     @ApiOperationSupport(order = 1)
     @PostMapping("/create")
-    public R<ReviewComment> createComment(@RequestBody ReviewCommentDto commentDto) {
-        log.info("ReviewCommentController.createComment?commentDto={}", commentDto);
-        if (commentDto.getUserId() == null) {
+    public R<ReviewComment> createComment(@RequestBody ReviewComment comment) {
+        log.info("ReviewCommentController.createComment?comment={}", comment);
+        if (comment.getUserId() == null) {
             return R.fail("用户未登录");
         }
-        return reviewCommentService.createComment(commentDto);
+        return reviewCommentService.createComment(comment);
     }
 
     @ApiOperation("根据评价ID查询评论列表")
@@ -58,21 +55,6 @@ public class ReviewCommentController {
         return reviewCommentService.getCommentListByReviewId(reviewId, currentUserId);
     }
 
-    @ApiOperation("删除评论(删除评论时,会级联删除该评论下的所有回复)")
-    @ApiOperationSupport(order = 3)
-    @ApiImplicitParams({
-            @ApiImplicitParam(name = "commentId", value = "评论ID", dataType = "int", paramType = "query", required = true),
-            @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "int", paramType = "query", required = true)
-    })
-    @PostMapping("/delete/commentId")
-    public R<Boolean> deleteComment(@RequestBody ReviewCommentRequestDto requestDto) {
-        log.info("ReviewCommentController.deleteComment?requestDto={}", requestDto);
-        if (requestDto.getUserId() == null) {
-            return R.fail("用户未登录");
-        }
-        return reviewCommentService.deleteComment(requestDto);
-    }
-
     @ApiOperation("点赞评论")
     @ApiOperationSupport(order = 4)
     @ApiImplicitParams({
@@ -80,11 +62,19 @@ public class ReviewCommentController {
             @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "int", paramType = "query", required = true)
     })
     @PostMapping("/like")
-    public R<Boolean> likeComment(@RequestBody ReviewCommentRequestDto requestDto) {
-        log.info("ReviewCommentController.likeComment?requestDto={}", requestDto);
-        if (requestDto.getUserId() == null) {
+    public R<Boolean> likeComment(@RequestBody ReviewComment reviewComment) {
+        Integer commentId = reviewComment.getId();
+        Integer userId = reviewComment.getUserId();
+        log.info("ReviewCommentController.likeComment?commentId={}, userId={}", commentId, userId);
+        if (userId == null) {
             return R.fail("用户未登录");
         }
+        if (commentId == null) {
+            return R.fail("评论ID不能为空");
+        }
+        ReviewCommentRequestDto requestDto = new ReviewCommentRequestDto();
+        requestDto.setCommentId(commentId);
+        requestDto.setUserId(userId);
         return reviewCommentService.likeComment(requestDto);
     }
 
@@ -95,11 +85,19 @@ public class ReviewCommentController {
             @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "int", paramType = "query", required = true)
     })
     @PostMapping("/cancelLike")
-    public R<Boolean> cancelLikeComment(@RequestBody ReviewCommentRequestDto requestDto) {
-        log.info("ReviewCommentController.cancelLikeComment?requestDto={}", requestDto);
-        if (requestDto.getUserId() == null) {
+    public R<Boolean> cancelLikeComment(@RequestBody ReviewComment reviewComment) {
+        Integer commentId = reviewComment.getId();
+        Integer userId = reviewComment.getUserId();
+        log.info("ReviewCommentController.cancelLikeComment?commentId={}, userId={}", commentId, userId);
+        if (userId == null) {
             return R.fail("用户未登录");
         }
+        if (commentId == null) {
+            return R.fail("评论ID不能为空");
+        }
+        ReviewCommentRequestDto requestDto = new ReviewCommentRequestDto();
+        requestDto.setCommentId(commentId);
+        requestDto.setUserId(userId);
         return reviewCommentService.cancelLikeComment(requestDto);
     }
 
@@ -145,38 +143,18 @@ public class ReviewCommentController {
         return reviewCommentService.deleteReply(replyId, userId);
     }
 
-    @ApiOperation("点赞回复")
-    @ApiOperationSupport(order = 9)
+    @ApiOperation(value = "删除评论(根据ID)", notes = "根据评论ID删除评论,userId有值时只能删除自己发布的评论,userId为空时允许删除任何评论(管理员删除)")
+    @ApiOperationSupport(order = 11)
     @ApiImplicitParams({
-            @ApiImplicitParam(name = "replyId", value = "回复ID", dataType = "int", paramType = "query", required = true),
-            @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "int", paramType = "query", required = true)
+            @ApiImplicitParam(name = "id", value = "评论ID", dataType = "int", paramType = "body", required = true),
+            @ApiImplicitParam(name = "userId", value = "用户ID(可选,有值时只能删除自己的评论,为空时允许删除任何评论)", dataType = "int", paramType = "body", required = false)
     })
-    @PostMapping("/reply/like")
-    public R<Boolean> likeReply(
-            @RequestParam Integer replyId,
-            @RequestParam Integer userId) {
-        log.info("ReviewCommentController.likeReply?replyId={}, userId={}", replyId, userId);
-        if (userId == null) {
-            return R.fail("用户未登录");
-        }
-        return reviewCommentService.likeReply(replyId, userId);
+    @PostMapping("/deleteReviewComment")
+    public R<Boolean> deleteReviewComment(@RequestBody ReviewComment reviewComment) {
+        log.info("ReviewCommentController.deleteReviewComment?reviewComment={}", reviewComment);
+        return reviewCommentService.deleteReviewComment(reviewComment);
     }
 
-    @ApiOperation("取消点赞回复")
-    @ApiOperationSupport(order = 10)
-    @ApiImplicitParams({
-            @ApiImplicitParam(name = "replyId", value = "回复ID", dataType = "int", paramType = "query", required = true),
-            @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "int", paramType = "query", required = true)
-    })
-    @PostMapping("/reply/cancelLike")
-    public R<Boolean> cancelLikeReply(
-            @RequestParam Integer replyId,
-            @RequestParam Integer userId) {
-        log.info("ReviewCommentController.cancelLikeReply?replyId={}, userId={}", replyId, userId);
-        if (userId == null) {
-            return R.fail("用户未登录");
-        }
-        return reviewCommentService.cancelLikeReply(replyId, userId);
-    }
+
 }
 

+ 28 - 26
alien-lawyer/src/main/java/shop/alien/lawyer/service/OrderReviewService.java

@@ -27,6 +27,33 @@ public interface OrderReviewService extends IService<OrderReview> {
     R<OrderReview> createReview(OrderReviewDto reviewDto);
 
     /**
+     * 获取评价详情(包含评论和回复)
+     *
+     * @param reviewId 评价ID
+     * @param currentUserId 当前用户ID(用于判断是否已点赞,可为null)
+     * @return R<OrderReviewDetailVo>
+     */
+    R<OrderReviewDetailVo> getReviewDetail(Integer reviewId, Integer currentUserId);
+
+    /**
+     * 点赞评价
+     *
+     * @param reviewId 评价ID
+     * @param userId 用户ID
+     * @return R<Boolean>
+     */
+    R<Boolean> likeReview(Integer reviewId, Integer userId);
+
+    /**
+     * 取消点赞评价
+     *
+     * @param reviewId 评价ID
+     * @param userId 用户ID
+     * @return R<Boolean>
+     */
+    R<Boolean> cancelLikeReview(Integer reviewId, Integer userId);
+
+    /**
      * 分页查询评价列表
      *
      * @param pageNum 页码
@@ -39,20 +66,12 @@ public interface OrderReviewService extends IService<OrderReview> {
      */
     R<IPage<OrderReviewVo>> getReviewList(int pageNum, int pageSize, Integer orderId, Integer lawyerUserId, Integer userId, Integer currentUserId);
 
-    /**
-     * 获取评价详情(包含评论和回复)
-     *
-     * @param reviewId 评价ID
-     * @param currentUserId 当前用户ID(用于判断是否已点赞,可为null)
-     * @return R<OrderReviewDetailVo>
-     */
-    R<OrderReviewDetailVo> getReviewDetail(Integer reviewId, Integer currentUserId);
 
     /**
      * 删除评价(删除评价时,会级联删除该评价下的所有评论和回复)
      *
      * @param reviewId 评价ID
-     * @param userId 用户ID(验证是否为评价用户
+     * @param userId 用户ID(可选,有值时只能删除自己的评价,为空时允许删除任何评价)
      * @return R<Boolean>
      */
     R<Boolean> deleteReview(Integer reviewId, Integer userId);
@@ -87,22 +106,5 @@ public interface OrderReviewService extends IService<OrderReview> {
      */
     R<IPage<OrderReviewVo>> getMyReviewList(int pageNum, int pageSize, Integer userId, Integer currentUserId);
 
-    /**
-     * 点赞评价
-     *
-     * @param reviewId 评价ID
-     * @param userId 用户ID
-     * @return R<Boolean>
-     */
-    R<Boolean> likeReview(Integer reviewId, Integer userId);
-
-    /**
-     * 取消点赞评价
-     *
-     * @param reviewId 评价ID
-     * @param userId 用户ID
-     * @return R<Boolean>
-     */
-    R<Boolean> cancelLikeReview(Integer reviewId, Integer userId);
 }
 

+ 6 - 25
alien-lawyer/src/main/java/shop/alien/lawyer/service/ReviewCommentService.java

@@ -3,7 +3,6 @@ package shop.alien.lawyer.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import shop.alien.entity.result.R;
 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;
@@ -21,11 +20,10 @@ public interface ReviewCommentService extends IService<ReviewComment> {
     /**
      * 创建评论(其他用户对评价的评论)
      *
-     * @param commentDto 评论DTO
-     *
+     * @param comment 评论实体
      * @return R<ReviewComment>
      */
-    R<ReviewComment> createComment(ReviewCommentDto commentDto);
+    R<ReviewComment> createComment(ReviewComment comment);
 
     /**
      * 根据评价ID查询评论列表
@@ -37,14 +35,6 @@ public interface ReviewCommentService extends IService<ReviewComment> {
     R<List<ReviewCommentVo>> getCommentListByReviewId(Integer reviewId, Integer currentUserId);
 
     /**
-     * 删除评论(删除评论时,会级联删除该评论下的所有回复)
-     *
-     * @param requestDto 请求DTO
-     * @return R<Boolean>
-     */
-    R<Boolean> deleteComment(ReviewCommentRequestDto requestDto);
-
-    /**
      * 点赞评论
      *
      * @param requestDto 请求DTO
@@ -87,21 +77,12 @@ public interface ReviewCommentService extends IService<ReviewComment> {
     R<Boolean> deleteReply(Integer replyId, Integer userId);
 
     /**
-     * 点赞回复
-     *
-     * @param replyId 回复ID
-     * @param userId 用户ID
-     * @return R<Boolean>
-     */
-    R<Boolean> likeReply(Integer replyId, Integer userId);
-
-    /**
-     * 取消点赞回复
+     * 删除评论(根据ID,物理删除)
+     * userId有值时只能删除自己发布的评论,userId为空时允许删除任何评论(管理员删除)
      *
-     * @param replyId 回复ID
-     * @param userId 用户ID
+     * @param reviewComment 评论对象(包含id和userId,userId可选)
      * @return R<Boolean>
      */
-    R<Boolean> cancelLikeReply(Integer replyId, Integer userId);
+    R<Boolean> deleteReviewComment(ReviewComment reviewComment);
 }
 

+ 52 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerUserServiceImpl.java

@@ -22,6 +22,7 @@ import shop.alien.lawyer.service.LawyerServiceAreaService;
 import shop.alien.lawyer.service.LawyerUserSearchHistoryService;
 import shop.alien.lawyer.service.LawyerUserService;
 import shop.alien.mapper.*;
+import shop.alien.entity.store.OrderReview;
 import shop.alien.util.common.ListToPage;
 
 import java.util.*;
@@ -48,6 +49,7 @@ public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerU
     private final LawFirmMapper lawFirmMapper;
     private final BaseRedisService baseRedisService;
     private final LawFirmPaymentMapper lawFirmPaymentmapper;
+    private final OrderReviewMapper orderReviewMapper;
 
     @Override
     public R<IPage<LawyerUser>> getLawyerUserList(int pageNum, int pageSize, String name, String phone, Integer status) {
@@ -202,6 +204,8 @@ public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerU
         // 为每个律师设置关联的法律问题场景列表
         if (pageResult.getRecords() != null && !pageResult.getRecords().isEmpty()) {
             setLawyerScenarios(pageResult.getRecords());
+            // 设置律师评价数
+            setLawyerReviewCounts(pageResult.getRecords());
         }
 
         return R.data(pageResult);
@@ -283,6 +287,52 @@ public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerU
                 .collect(Collectors.toMap(LawyerLegalProblemScenario::getId, s -> s, (k1, k2) -> k1));
     }
 
+    /**
+     * 批量设置律师的评价数(只统计评价,不包含评论)
+     *
+     * @param lawyers 律师列表
+     */
+    private void setLawyerReviewCounts(List<LawyerUser> lawyers) {
+        if (CollectionUtils.isEmpty(lawyers)) {
+            return;
+        }
+
+        List<Integer> lawyerIds = lawyers.stream()
+                .map(LawyerUser::getId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+
+        if (lawyerIds.isEmpty()) {
+            return;
+        }
+
+        try {
+            // 批量查询每个律师的评价数
+            LambdaQueryWrapper<OrderReview> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.in(OrderReview::getLawyerUserId, lawyerIds)
+                    .eq(OrderReview::getDeleteFlag, 0)
+                    .select(OrderReview::getLawyerUserId);
+            List<OrderReview> reviews = orderReviewMapper.selectList(queryWrapper);
+
+            // 按律师ID分组统计评价数
+            Map<Integer, Long> reviewCountMap = reviews.stream()
+                    .filter(r -> r.getLawyerUserId() != null)
+                    .collect(Collectors.groupingBy(OrderReview::getLawyerUserId, Collectors.counting()));
+
+            // 为每个律师设置评价数
+            lawyers.forEach(lawyer -> {
+                Long count = reviewCountMap.get(lawyer.getId());
+                lawyer.setReviewCount(count != null ? count.intValue() : 0);
+            });
+
+            log.debug("批量设置律师评价数完成,律师数量={}", lawyers.size());
+        } catch (Exception e) {
+            log.error("批量设置律师评价数失败,错误信息={}", e.getMessage(), e);
+            // 设置失败时,将所有律师的评价数设置为0
+            lawyers.forEach(lawyer -> lawyer.setReviewCount(0));
+        }
+    }
+
 
     @Override
     public R<IPage<LawyerUser>> getRecommendedLawyersBySession(String sessionId, Integer messageId) {
@@ -352,6 +402,8 @@ public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerU
         // 为每个律师设置关联的法律问题场景列表
         if (pageResult.getRecords() != null && !pageResult.getRecords().isEmpty()) {
             setLawyerScenarios(pageResult.getRecords());
+            // 设置律师评价数
+            setLawyerReviewCounts(pageResult.getRecords());
         }
 
         return R.data(pageResult);

+ 95 - 27
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/OrderReviewServiceImpl.java

@@ -11,6 +11,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.LawyerConsultationOrder;
 import shop.alien.entity.store.LifeLikeRecord;
@@ -22,12 +23,16 @@ import shop.alien.entity.store.vo.OrderReviewVo;
 import shop.alien.entity.store.vo.PendingReviewVo;
 import shop.alien.lawyer.service.OrderReviewService;
 import shop.alien.lawyer.service.ReviewCommentService;
-import shop.alien.mapper.*;
+import shop.alien.entity.store.LawyerUser;
+import shop.alien.mapper.LawyerConsultationOrderMapper;
+import shop.alien.mapper.LawyerUserMapper;
+import shop.alien.mapper.LifeLikeRecordMapper;
+import shop.alien.mapper.OrderReviewMapper;
+import shop.alien.mapper.ReviewCommentMapper;
 
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
-import org.springframework.util.CollectionUtils;
 
 /**
  * 订单评价 服务实现类
@@ -46,6 +51,7 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
     private final ReviewCommentService reviewCommentService;
     private final ReviewCommentMapper reviewCommentMapper;
     private final LifeLikeRecordMapper lifeLikeRecordMapper;
+    private final LawyerUserMapper lawyerUserMapper;
 
     @Override
     public R<OrderReview> createReview(OrderReviewDto reviewDto) {
@@ -119,6 +125,8 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
         boolean success = this.save(review);
         if (success) {
             log.info("创建评价成功,评价ID={}", review.getId());
+            // 更新律师评分
+            updateLawyerServiceScore(review.getLawyerUserId());
             return R.data(review, "评价成功");
         } else {
             log.error("创建评价失败");
@@ -126,6 +134,50 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
         }
     }
 
+    /**
+     * 更新律师服务评分
+     * 计算公式:律师评分 = (overallRating平均值) * 20 (转换为0-100分)
+     *
+     * @param lawyerUserId 律师用户ID
+     */
+    private void updateLawyerServiceScore(Integer lawyerUserId) {
+        if (lawyerUserId == null) {
+            log.warn("更新律师评分失败:律师ID为空");
+            return;
+        }
+
+        try {
+            // 计算平均评分(1-5星)
+            Double averageRating = orderReviewMapper.getAverageRatingByLawyerUserId(lawyerUserId);
+            
+            Integer serviceScore;
+            if (averageRating != null) {
+                // 转换为0-100分:service_score = averageRating * 20
+                serviceScore = (int) Math.round(averageRating * 20);
+                // 确保在0-100范围内
+                serviceScore = Math.max(0, Math.min(100, serviceScore));
+            } else {
+                // 如果没有评价,设置为0
+                serviceScore = 0;
+                log.info("律师暂无评价,将评分设置为0,律师ID={}", lawyerUserId);
+            }
+            
+            // 更新律师评分
+            LambdaUpdateWrapper<LawyerUser> updateWrapper = new LambdaUpdateWrapper<>();
+            updateWrapper.eq(LawyerUser::getId, lawyerUserId);
+            updateWrapper.set(LawyerUser::getServiceScore, serviceScore);
+            int result = lawyerUserMapper.update(null, updateWrapper);
+            
+            if (result > 0) {
+                log.info("更新律师评分成功,律师ID={}, 平均评分={}, 服务评分={}", lawyerUserId, averageRating, serviceScore);
+            } else {
+                log.warn("更新律师评分失败,律师ID={}", lawyerUserId);
+            }
+        } catch (Exception e) {
+            log.error("更新律师评分异常,律师ID={}, 错误信息={}", lawyerUserId, e.getMessage(), e);
+        }
+    }
+
     @Override
     public R<IPage<OrderReviewVo>> getReviewList(int pageNum, int pageSize, Integer orderId, Integer lawyerUserId, Integer userId, Integer currentUserId) {
         log.info("OrderReviewServiceImpl.getReviewList?pageNum={}, pageSize={}, orderId={}, lawyerUserId={}, userId={}, currentUserId={}",
@@ -160,16 +212,19 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
         if (reviewVo == null) {
             return R.fail("评价不存在");
         }
+        log.debug("查询评价详情,reviewId={}, currentUserId={}, isLiked={}", reviewId, currentUserId, reviewVo.getIsLiked());
 
-        // 处理评价图片
-        OrderReview review = this.getById(reviewId);
-        if (review != null && review.getReviewImages() != null) {
+        // 处理评价图片:从SQL查询结果中解析JSON字符串
+        if (reviewVo.getReviewImagesJson() != null && !reviewVo.getReviewImagesJson().trim().isEmpty()) {
             try {
-                List<String> images = JSON.parseArray(review.getReviewImages(), String.class);
-                reviewVo.setReviewImages(images);
+                List<String> images = JSON.parseArray(reviewVo.getReviewImagesJson(), String.class);
+                reviewVo.setReviewImages(images != null ? images : new ArrayList<>());
             } catch (Exception e) {
                 log.warn("解析评价图片失败:{}", e.getMessage());
+                reviewVo.setReviewImages(new ArrayList<>());
             }
+        } else {
+            reviewVo.setReviewImages(new ArrayList<>());
         }
 
         // 查询评论列表
@@ -183,14 +238,20 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
             }
         }
         
+        // 查询总评论数(包括首评论和子评论)
+        Integer totalCommentCount = reviewCommentMapper.getTotalCommentCountByReviewId(reviewId);
+        if (totalCommentCount == null) {
+            totalCommentCount = 0;
+        }
+        
         // 构建返回结果
         OrderReviewDetailVo detailVo = new OrderReviewDetailVo();
         detailVo.setReview(reviewVo);
-        detailVo.setComments(comments);
-        detailVo.setTotalCommentCount(comments != null ? comments.size() : 0);
+        detailVo.setComments(comments != null ? comments : new ArrayList<>());
+        detailVo.setTotalCommentCount(totalCommentCount);
         // 设置评价的点赞数和是否已点赞(从 reviewVo 中获取)
-        detailVo.setLikeCount(reviewVo.getLikeCount());
-        detailVo.setIsLiked(reviewVo.getIsLiked());
+        detailVo.setLikeCount(reviewVo.getLikeCount() != null ? reviewVo.getLikeCount() : 0);
+        detailVo.setIsLiked(reviewVo.getIsLiked() != null ? reviewVo.getIsLiked() : 0);
 
         return R.data(detailVo);
     }
@@ -202,9 +263,6 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
         if (reviewId == null) {
             return R.fail("评价ID不能为空");
         }
-        if (userId == null) {
-            return R.fail("用户ID不能为空");
-        }
 
         // 查询评价
         OrderReview review = this.getById(reviewId);
@@ -212,9 +270,11 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
             return R.fail("评价不存在");
         }
 
-        // 验证是否为评价用户
-        if (!review.getUserId().equals(userId)) {
-            return R.fail("只能删除自己的评价");
+        // 当userId有值时,验证是否为评价用户(只能删除自己的评价)
+        if (userId != null) {
+            if (!review.getUserId().equals(userId)) {
+                return R.fail("只能删除自己的评价");
+            }
         }
 
         // 查询该评价下的所有评论
@@ -244,18 +304,29 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
                         .eq(ReviewComment::getHeadType, 1)
                         .eq(ReviewComment::getDeleteFlag, 0);
                 replyUpdateWrapper.set(ReviewComment::getDeleteFlag, 1);
-                replyUpdateWrapper.set(ReviewComment::getUpdatedUserId, userId);
+                if (userId != null) {
+                    replyUpdateWrapper.set(ReviewComment::getUpdatedUserId, userId);
+                }
                 replyUpdateWrapper.set(ReviewComment::getUpdatedTime, new Date());
                 reviewCommentService.update(replyUpdateWrapper);
                 
                 // 删除评论
                 comment.setDeleteFlag(1);
-                comment.setUpdatedUserId(userId);
+                if (userId != null) {
+                    comment.setUpdatedUserId(userId);
+                }
                 comment.setUpdatedTime(new Date());
                 reviewCommentService.updateById(comment);
             }
             
-            log.info("删除评价成功,评价ID={}", reviewId);
+            // 更新律师评分
+            updateLawyerServiceScore(review.getLawyerUserId());
+            
+            if (userId != null) {
+                log.info("删除评价成功,评价ID={}, 操作人ID={}", reviewId, userId);
+            } else {
+                log.info("管理员删除评价成功,评价ID={}", reviewId);
+            }
             return R.data(true, "删除成功");
         } else {
             log.error("删除评价失败,评价ID={}", reviewId);
@@ -422,17 +493,14 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
         if (!CollectionUtils.isEmpty(records)) {
             // 删除点赞记录(逻辑删除)
             for (LifeLikeRecord record : records) {
-                record.setDeleteFlag(1);
-                record.setUpdatedUserId(userId);
-                record.setUpdatedTime(new Date());
-                lifeLikeRecordMapper.updateById(record);
+                int updateResult = lifeLikeRecordMapper.deleteById(record.getId());
+                log.info("逻辑删除点赞记录,recordId={}, updateResult={}", record.getId(), updateResult);
             }
 
-            // 更新评价点赞数
+            // 更新评价点赞数(移除 gt 条件,确保即使为 0 也能正确更新)
             LambdaUpdateWrapper<OrderReview> updateWrapper = new LambdaUpdateWrapper<>();
             updateWrapper.eq(OrderReview::getId, reviewId);
-            updateWrapper.gt(OrderReview::getLikeCount, 0);
-            updateWrapper.setSql("like_count = like_count - 1");
+            updateWrapper.setSql("like_count = GREATEST(0, like_count - 1)");
             int result = orderReviewMapper.update(null, updateWrapper);
 
             if (result > 0) {

+ 113 - 177
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/ReviewCommentServiceImpl.java

@@ -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("删除失败");
     }
 }