Forráskód Böngészése

同步代码 dev同步到sit

LuTong 3 hete
szülő
commit
5820057f74

+ 30 - 26
alien-entity/src/main/java/shop/alien/entity/store/LawyerUser.java

@@ -144,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 = "执业开始日期")
@@ -153,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;
@@ -308,30 +333,9 @@ public class LawyerUser extends Model<LawyerUser> {
     @TableField(exist = false)
     private String moneyStr;
 
-    /**
-     * 获取执业年限(根据执业开始日期自动计算)
-     * 返回当前时间减去执业开始时间的年数
-     *
-     * @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(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;
 }
 

+ 32 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/LawyerReviewStatisticsVo.java

@@ -0,0 +1,32 @@
+package shop.alien.entity.store.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 律师评价统计数据VO
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "LawyerReviewStatisticsVo对象", description = "律师评价统计数据VO")
+public class LawyerReviewStatisticsVo {
+
+    @ApiModelProperty(value = "全部评价数量")
+    private Integer totalCount;
+
+    @ApiModelProperty(value = "好评数量(4.5-5分)")
+    private Integer goodCount;
+
+    @ApiModelProperty(value = "中评数量(3-4分)")
+    private Integer mediumCount;
+
+    @ApiModelProperty(value = "差评数量(0-2.5分)")
+    private Integer badCount;
+
+    @ApiModelProperty(value = "有图评价数量")
+    private Integer imageCount;
+}
+

+ 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;
 

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

@@ -112,5 +112,21 @@ public interface OrderReviewMapper extends BaseMapper<OrderReview> {
             @Param("type") Integer type,
             @Param("currentUserId") Integer currentUserId
     );
+
+    /**
+     * 统计律师的全部评价数量
+     *
+     * @param lawyerUserId 律师用户ID
+     * @return 全部评价数量
+     */
+    Integer getTotalReviewCountByLawyerUserId(@Param("lawyerUserId") Integer lawyerUserId);
+
+    /**
+     * 统计律师的有图评价数量
+     *
+     * @param lawyerUserId 律师用户ID
+     * @return 有图评价数量
+     */
+    Integer getImageReviewCountByLawyerUserId(@Param("lawyerUserId") Integer lawyerUserId);
 }
 

+ 28 - 0
alien-entity/src/main/resources/mapper/OrderReviewMapper.xml

@@ -215,6 +215,15 @@
         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>
+
     <!-- 统计律师的好评数(4.5-5分) -->
     <select id="getGoodReviewCountByLawyerUserId" resultType="java.lang.Integer">
         <![CDATA[
@@ -254,6 +263,25 @@
         ]]>
     </select>
 
+    <!-- 统计律师的全部评价数量 -->
+    <select id="getTotalReviewCountByLawyerUserId" resultType="java.lang.Integer">
+        SELECT COUNT(*)
+        FROM lawyer_order_review
+        WHERE lawyer_user_id = #{lawyerUserId}
+        AND delete_flag = 0
+    </select>
+
+    <!-- 统计律师的有图评价数量 -->
+    <select id="getImageReviewCountByLawyerUserId" resultType="java.lang.Integer">
+        SELECT COUNT(*)
+        FROM lawyer_order_review
+        WHERE lawyer_user_id = #{lawyerUserId}
+        AND delete_flag = 0
+        AND review_images IS NOT NULL
+        AND review_images != ''
+        AND TRIM(review_images) != ''
+    </select>
+
     <!-- 根据律师ID和类型分页查询评价列表(包含用户和律师信息) -->
     <select id="getReviewListByLawyerAndType" resultMap="OrderReviewVoResultMap">
         SELECT

+ 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.entity.store.dto.LawyerLegalProblemScenarioStatusDto;
 import shop.alien.lawyer.service.LawyerLegalProblemScenarioService;
@@ -93,12 +91,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);
     }
 

+ 105 - 24
alien-lawyer/src/main/java/shop/alien/lawyer/controller/OrderReviewController.java

@@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.OrderReview;
 import shop.alien.entity.store.dto.OrderReviewDto;
+import shop.alien.entity.store.vo.LawyerReviewStatisticsVo;
 import shop.alien.entity.store.vo.OrderReviewDetailVo;
 import shop.alien.entity.store.vo.OrderReviewVo;
 import shop.alien.entity.store.vo.PendingReviewVo;
@@ -41,6 +42,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({
@@ -132,38 +187,64 @@ public class OrderReviewController {
         return orderReviewService.getMyReviewList(page, size, userId, currentUserId);
     }
 
-    @ApiOperation("点赞评价")
-    @ApiOperationSupport(order = 8)
+    @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)
+            @ApiImplicitParam(name = "lawyerUserId", 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("用户未登录");
+    @GetMapping("/statistics")
+    public R<LawyerReviewStatisticsVo> getLawyerReviewStatistics(@RequestParam Integer lawyerUserId) {
+        log.info("OrderReviewController.getLawyerReviewStatistics?lawyerUserId={}", lawyerUserId);
+        if (lawyerUserId == null) {
+            return R.fail("律师ID不能为空");
         }
-        return orderReviewService.likeReview(reviewId, userId);
+        return orderReviewService.getLawyerReviewStatistics(lawyerUserId);
     }
 
-    @ApiOperation("取消点赞评价")
-    @ApiOperationSupport(order = 9)
+    @ApiOperation("根据律师ID分页查询评价列表(查询指定律师的所有评价)")
+    @ApiOperationSupport(order = 10)
     @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 = "page", value = "页数(默认1)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "size", value = "页容(默认10)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "lawyerUserId", value = "律师用户ID", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "currentUserId", value = "当前用户ID(用于判断是否已点赞)", dataType = "int", paramType = "query")
     })
-    @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("用户未登录");
+    @GetMapping("/list/byLawyer")
+    public R<IPage<OrderReviewVo>> getReviewListByLawyer(
+            @RequestParam(defaultValue = "1") int page,
+            @RequestParam(defaultValue = "10") int size,
+            @RequestParam Integer lawyerUserId,
+            @RequestParam(required = false) Integer currentUserId) {
+        log.info("OrderReviewController.getReviewListByLawyer?page={}, size={}, lawyerUserId={}, currentUserId={}",
+                page, size, lawyerUserId, currentUserId);
+        if (lawyerUserId == null) {
+            return R.fail("律师ID不能为空");
         }
-        return orderReviewService.cancelLikeReview(reviewId, userId);
+        return orderReviewService.getReviewList(page, size, null, lawyerUserId, null, currentUserId);
+    }
+
+    @ApiOperation("根据律师ID和类型分页查询评价列表(不包含评论)")
+    @ApiOperationSupport(order = 11)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page", value = "页数(默认1)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "size", value = "页容(默认10)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "lawyerUserId", value = "律师用户ID", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "type", value = "查询分类(1:好评,2:中评,3:差评,4:有图,为空时返回全部)", dataType = "int", paramType = "query", required = false),
+            @ApiImplicitParam(name = "currentUserId", value = "当前用户ID(用于判断是否已点赞)", dataType = "int", paramType = "query")
+    })
+    @GetMapping("/list/byLawyerAndType")
+    public R<IPage<OrderReviewVo>> getReviewListByLawyerAndType(
+            @RequestParam(defaultValue = "1") int page,
+            @RequestParam(defaultValue = "10") int size,
+            @RequestParam Integer lawyerUserId,
+            @RequestParam(required = false) Integer type,
+            @RequestParam(required = false) Integer currentUserId) {
+        log.info("OrderReviewController.getReviewListByLawyerAndType?page={}, size={}, lawyerUserId={}, type={}, currentUserId={}",
+                page, size, lawyerUserId, type, currentUserId);
+        if (lawyerUserId == null) {
+            return R.fail("律师ID不能为空");
+        }
+        return orderReviewService.getReviewListByLawyerAndType(page, size, lawyerUserId, type, currentUserId);
     }
 }
 

+ 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);
-    }
+
 }
 

+ 36 - 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);
@@ -88,23 +107,6 @@ 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);
-    /**
      * 根据律师ID和类型分页查询评价列表(不包含评论)
      *
      * @param pageNum 页码
@@ -116,5 +118,13 @@ public interface OrderReviewService extends IService<OrderReview> {
      */
     R<IPage<OrderReviewVo>> getReviewListByLawyerAndType(int pageNum, int pageSize, Integer lawyerUserId, Integer type, Integer currentUserId);
 
+    /**
+     * 获取律师评价统计数据
+     *
+     * @param lawyerUserId 律师用户ID
+     * @return R<LawyerReviewStatisticsVo>
+     */
+    R<shop.alien.entity.store.vo.LawyerReviewStatisticsVo> getLawyerReviewStatistics(Integer lawyerUserId);
+
 }
 

+ 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);
 }
 

+ 51 - 1
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerUserServiceImpl.java

@@ -8,7 +8,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 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.util.CollectionUtils;
@@ -52,6 +51,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) {
@@ -206,6 +206,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);
@@ -287,6 +289,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) {
@@ -356,6 +404,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);

+ 54 - 3
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/OrderReviewServiceImpl.java

@@ -18,6 +18,7 @@ import shop.alien.entity.store.LifeLikeRecord;
 import shop.alien.entity.store.OrderReview;
 import shop.alien.entity.store.ReviewComment;
 import shop.alien.entity.store.dto.OrderReviewDto;
+import shop.alien.entity.store.vo.LawyerReviewStatisticsVo;
 import shop.alien.entity.store.vo.OrderReviewDetailVo;
 import shop.alien.entity.store.vo.OrderReviewVo;
 import shop.alien.entity.store.vo.PendingReviewVo;
@@ -210,9 +211,17 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
         // 处理评价图片JSON字符串转换为列表
         if (result.getRecords() != null) {
             for (OrderReviewVo vo : result.getRecords()) {
-                if (vo.getReviewImages() != null && !vo.getReviewImages().isEmpty()) {
-                    // 如果已经是列表,则不需要转换
-                    // 这里假设VO中的reviewImages已经是List<String>类型
+                // 处理评价图片:从JSON字符串解析为List
+                if (vo.getReviewImagesJson() != null && !vo.getReviewImagesJson().trim().isEmpty()) {
+                    try {
+                        List<String> images = JSON.parseArray(vo.getReviewImagesJson(), String.class);
+                        vo.setReviewImages(images != null ? images : new ArrayList<>());
+                    } catch (Exception e) {
+                        log.warn("解析评价图片失败:{}", e.getMessage());
+                        vo.setReviewImages(new ArrayList<>());
+                    }
+                } else {
+                    vo.setReviewImages(new ArrayList<>());
                 }
             }
         }
@@ -567,5 +576,47 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
 
         return R.data(result);
     }
+
+    @Override
+    public R<LawyerReviewStatisticsVo> getLawyerReviewStatistics(Integer lawyerUserId) {
+        log.info("OrderReviewServiceImpl.getLawyerReviewStatistics?lawyerUserId={}", lawyerUserId);
+
+        if (lawyerUserId == null) {
+            return R.fail("律师ID不能为空");
+        }
+
+        try {
+            LawyerReviewStatisticsVo statistics = new LawyerReviewStatisticsVo();
+
+            // 统计全部评价数量
+            Integer totalCount = orderReviewMapper.getTotalReviewCountByLawyerUserId(lawyerUserId);
+            statistics.setTotalCount(totalCount != null ? totalCount : 0);
+
+            // 统计好评数量
+            Integer goodCount = orderReviewMapper.getGoodReviewCountByLawyerUserId(lawyerUserId);
+            statistics.setGoodCount(goodCount != null ? goodCount : 0);
+
+            // 统计中评数量
+            Integer mediumCount = orderReviewMapper.getMediumReviewCountByLawyerUserId(lawyerUserId);
+            statistics.setMediumCount(mediumCount != null ? mediumCount : 0);
+
+            // 统计差评数量
+            Integer badCount = orderReviewMapper.getBadReviewCountByLawyerUserId(lawyerUserId);
+            statistics.setBadCount(badCount != null ? badCount : 0);
+
+            // 统计有图评价数量
+            Integer imageCount = orderReviewMapper.getImageReviewCountByLawyerUserId(lawyerUserId);
+            statistics.setImageCount(imageCount != null ? imageCount : 0);
+
+            log.info("获取律师评价统计数据成功,律师ID={}, 全部={}, 好评={}, 中评={}, 差评={}, 有图={}",
+                    lawyerUserId, statistics.getTotalCount(), statistics.getGoodCount(),
+                    statistics.getMediumCount(), statistics.getBadCount(), statistics.getImageCount());
+
+            return R.data(statistics);
+        } catch (Exception e) {
+            log.error("获取律师评价统计数据异常,律师ID={}, 错误信息={}", lawyerUserId, e.getMessage(), e);
+            return R.fail("获取统计数据失败");
+        }
+    }
 }
 

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