Ver Fonte

评论代码提交,实际代码是柳东志的,出问题他负责

zhangchen há 3 semanas atrás
pai
commit
8f7ac2918b
25 ficheiros alterados com 1896 adições e 0 exclusões
  1. 76 0
      alien-entity/src/main/java/shop/alien/entity/store/CommentReply.java
  2. 104 0
      alien-entity/src/main/java/shop/alien/entity/store/OrderReview.java
  3. 72 0
      alien-entity/src/main/java/shop/alien/entity/store/ReviewComment.java
  4. 29 0
      alien-entity/src/main/java/shop/alien/entity/store/dto/CommentReplyDto.java
  5. 46 0
      alien-entity/src/main/java/shop/alien/entity/store/dto/OrderReviewDto.java
  6. 23 0
      alien-entity/src/main/java/shop/alien/entity/store/dto/ReviewCommentDto.java
  7. 58 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/CommentReplyVo.java
  8. 30 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/OrderReviewDetailVo.java
  9. 82 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/OrderReviewVo.java
  10. 52 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/ReviewCommentVo.java
  11. 44 0
      alien-entity/src/main/java/shop/alien/mapper/CommentReplyMapper.java
  12. 54 0
      alien-entity/src/main/java/shop/alien/mapper/OrderReviewMapper.java
  13. 36 0
      alien-entity/src/main/java/shop/alien/mapper/ReviewCommentMapper.java
  14. 60 0
      alien-entity/src/main/resources/mapper/CommentReplyMapper.xml
  15. 147 0
      alien-entity/src/main/resources/mapper/OrderReviewMapper.xml
  16. 46 0
      alien-entity/src/main/resources/mapper/ReviewCommentMapper.xml
  17. 68 0
      alien-lawyer/src/main/java/shop/alien/lawyer/controller/CommentReplyController.java
  18. 98 0
      alien-lawyer/src/main/java/shop/alien/lawyer/controller/OrderReviewController.java
  19. 68 0
      alien-lawyer/src/main/java/shop/alien/lawyer/controller/ReviewCommentController.java
  20. 45 0
      alien-lawyer/src/main/java/shop/alien/lawyer/service/CommentReplyService.java
  21. 65 0
      alien-lawyer/src/main/java/shop/alien/lawyer/service/OrderReviewService.java
  22. 45 0
      alien-lawyer/src/main/java/shop/alien/lawyer/service/ReviewCommentService.java
  23. 140 0
      alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/CommentReplyServiceImpl.java
  24. 257 0
      alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/OrderReviewServiceImpl.java
  25. 151 0
      alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/ReviewCommentServiceImpl.java

+ 76 - 0
alien-entity/src/main/java/shop/alien/entity/store/CommentReply.java

@@ -0,0 +1,76 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 评论回复表
+ * 用户对评论的回复(支持嵌套回复)
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@JsonInclude
+@TableName("comment_reply")
+@ApiModel(value = "CommentReply对象", description = "评论回复")
+public class CommentReply {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "评论ID")
+    @TableField("comment_id")
+    private Integer commentId;
+
+    @ApiModelProperty(value = "回复用户ID")
+    @TableField("user_id")
+    private Integer userId;
+
+    @ApiModelProperty(value = "被回复用户ID(如果是回复评论,则为评论用户ID;如果是回复回复,则为被回复用户ID)")
+    @TableField("reply_to_user_id")
+    private Integer replyToUserId;
+
+    @ApiModelProperty(value = "父回复ID(如果是回复评论,则为0;如果是回复回复,则为父回复ID)")
+    @TableField("parent_reply_id")
+    private Integer parentReplyId;
+
+    @ApiModelProperty(value = "回复内容")
+    @TableField("reply_content")
+    private String replyContent;
+
+    @ApiModelProperty(value = "点赞数")
+    @TableField("like_count")
+    private Integer likeCount;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}
+

+ 104 - 0
alien-entity/src/main/java/shop/alien/entity/store/OrderReview.java

@@ -0,0 +1,104 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 订单评价表
+ * 订单用户对订单的评价和评分
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@JsonInclude
+@TableName("order_review")
+@ApiModel(value = "OrderReview对象", description = "订单评价")
+public class OrderReview {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "订单ID")
+    @TableField("order_id")
+    private Integer orderId;
+
+    @ApiModelProperty(value = "订单编号")
+    @TableField("order_number")
+    private String orderNumber;
+
+    @ApiModelProperty(value = "评价用户ID(订单用户)")
+    @TableField("user_id")
+    private Integer userId;
+
+    @ApiModelProperty(value = "律师用户ID")
+    @TableField("lawyer_user_id")
+    private Integer lawyerUserId;
+
+    @ApiModelProperty(value = "总体评分(1-5星,支持0.5星)")
+    @TableField("overall_rating")
+    private Double overallRating;
+
+    @ApiModelProperty(value = "服务态度评分(1-5星,支持0.5星)")
+    @TableField("service_attitude_rating")
+    private Double serviceAttitudeRating;
+
+    @ApiModelProperty(value = "响应时间评分(1-5星,支持0.5星)")
+    @TableField("response_time_rating")
+    private Double responseTimeRating;
+
+    @ApiModelProperty(value = "专业能力评分(1-5星,支持0.5星)")
+    @TableField("professional_ability_rating")
+    private Double professionalAbilityRating;
+
+    @ApiModelProperty(value = "评价内容")
+    @TableField("review_content")
+    private String reviewContent;
+
+    @ApiModelProperty(value = "评价图片(JSON数组格式存储图片URL)")
+    @TableField("review_images")
+    private String reviewImages;
+
+    @ApiModelProperty(value = "是否匿名评价,0:否,1:是")
+    @TableField("is_anonymous")
+    private Integer isAnonymous;
+
+    @ApiModelProperty(value = "点赞数")
+    @TableField("like_count")
+    private Integer likeCount;
+
+    @ApiModelProperty(value = "评论数")
+    @TableField("comment_count")
+    private Integer commentCount;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}
+

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

@@ -0,0 +1,72 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 评价评论表
+ * 其他用户对订单评价的评论
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@JsonInclude
+@TableName("review_comment")
+@ApiModel(value = "ReviewComment对象", description = "评价评论")
+public class ReviewComment {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "评价ID")
+    @TableField("review_id")
+    private Integer reviewId;
+
+    @ApiModelProperty(value = "评论用户ID")
+    @TableField("user_id")
+    private Integer userId;
+
+    @ApiModelProperty(value = "评论内容")
+    @TableField("comment_content")
+    private String commentContent;
+
+    @ApiModelProperty(value = "点赞数")
+    @TableField("like_count")
+    private Integer likeCount;
+
+    @ApiModelProperty(value = "回复数")
+    @TableField("reply_count")
+    private Integer replyCount;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}
+

+ 29 - 0
alien-entity/src/main/java/shop/alien/entity/store/dto/CommentReplyDto.java

@@ -0,0 +1,29 @@
+package shop.alien.entity.store.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 评论回复DTO
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "CommentReplyDto对象", description = "评论回复DTO")
+public class CommentReplyDto {
+
+    @ApiModelProperty(value = "评论ID")
+    private Integer commentId;
+
+    @ApiModelProperty(value = "被回复用户ID(如果是回复评论,则为评论用户ID;如果是回复回复,则为被回复用户ID)")
+    private Integer replyToUserId;
+
+    @ApiModelProperty(value = "父回复ID(如果是回复评论,则为0;如果是回复回复,则为父回复ID)")
+    private Integer parentReplyId;
+
+    @ApiModelProperty(value = "回复内容")
+    private String replyContent;
+}
+

+ 46 - 0
alien-entity/src/main/java/shop/alien/entity/store/dto/OrderReviewDto.java

@@ -0,0 +1,46 @@
+package shop.alien.entity.store.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 订单评价DTO
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "OrderReviewDto对象", description = "订单评价DTO")
+public class OrderReviewDto {
+
+    @ApiModelProperty(value = "订单ID")
+    private Integer orderId;
+
+    @ApiModelProperty(value = "订单编号")
+    private String orderNumber;
+
+    @ApiModelProperty(value = "总体评分(1-5星,支持0.5星)")
+    private Double overallRating;
+
+    @ApiModelProperty(value = "服务态度评分(1-5星,支持0.5星)")
+    private Double serviceAttitudeRating;
+
+    @ApiModelProperty(value = "响应时间评分(1-5星,支持0.5星)")
+    private Double responseTimeRating;
+
+    @ApiModelProperty(value = "专业能力评分(1-5星,支持0.5星)")
+    private Double professionalAbilityRating;
+
+    @ApiModelProperty(value = "评价内容")
+    private String reviewContent;
+
+    @ApiModelProperty(value = "评价图片列表")
+    private List<String> reviewImages;
+
+    @ApiModelProperty(value = "是否匿名评价,0:否,1:是")
+    private Integer isAnonymous;
+}
+

+ 23 - 0
alien-entity/src/main/java/shop/alien/entity/store/dto/ReviewCommentDto.java

@@ -0,0 +1,23 @@
+package shop.alien.entity.store.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 评价评论DTO
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "ReviewCommentDto对象", description = "评价评论DTO")
+public class ReviewCommentDto {
+
+    @ApiModelProperty(value = "评价ID")
+    private Integer reviewId;
+
+    @ApiModelProperty(value = "评论内容")
+    private String commentContent;
+}
+

+ 58 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/CommentReplyVo.java

@@ -0,0 +1,58 @@
+package shop.alien.entity.store.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 评论回复VO
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "CommentReplyVo对象", description = "评论回复VO")
+public class CommentReplyVo {
+
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+
+    @ApiModelProperty(value = "评论ID")
+    private Integer commentId;
+
+    @ApiModelProperty(value = "回复用户ID")
+    private Integer userId;
+
+    @ApiModelProperty(value = "回复用户名称")
+    private String userName;
+
+    @ApiModelProperty(value = "回复用户头像")
+    private String userAvatar;
+
+    @ApiModelProperty(value = "被回复用户ID")
+    private Integer replyToUserId;
+
+    @ApiModelProperty(value = "被回复用户名称")
+    private String replyToUserName;
+
+    @ApiModelProperty(value = "父回复ID")
+    private Integer parentReplyId;
+
+    @ApiModelProperty(value = "回复内容")
+    private String replyContent;
+
+    @ApiModelProperty(value = "点赞数")
+    private Integer likeCount;
+
+    @ApiModelProperty(value = "子回复列表")
+    private List<CommentReplyVo> childReplies;
+
+    @ApiModelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+}
+

+ 30 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/OrderReviewDetailVo.java

@@ -0,0 +1,30 @@
+package shop.alien.entity.store.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 订单评价详情VO(包含评论和回复)
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "OrderReviewDetailVo对象", description = "订单评价详情VO")
+public class OrderReviewDetailVo {
+
+    @ApiModelProperty(value = "评价信息")
+    private OrderReviewVo review;
+
+    @ApiModelProperty(value = "评论列表")
+    private List<ReviewCommentVo> comments;
+
+    @ApiModelProperty(value = "总评论数")
+    private Integer totalCommentCount;
+}
+

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

@@ -0,0 +1,82 @@
+package shop.alien.entity.store.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 订单评价VO
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "OrderReviewVo对象", description = "订单评价VO")
+public class OrderReviewVo {
+
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+
+    @ApiModelProperty(value = "订单ID")
+    private Integer orderId;
+
+    @ApiModelProperty(value = "订单编号")
+    private String orderNumber;
+
+    @ApiModelProperty(value = "评价用户ID")
+    private Integer userId;
+
+    @ApiModelProperty(value = "评价用户名称")
+    private String userName;
+
+    @ApiModelProperty(value = "评价用户头像")
+    private String userAvatar;
+
+    @ApiModelProperty(value = "律师用户ID")
+    private Integer lawyerUserId;
+
+    @ApiModelProperty(value = "律师名称")
+    private String lawyerName;
+
+    @ApiModelProperty(value = "律师头像")
+    private String lawyerAvatar;
+
+    @ApiModelProperty(value = "律所名称")
+    private String lawFirmName;
+
+    @ApiModelProperty(value = "总体评分")
+    private Double overallRating;
+
+    @ApiModelProperty(value = "服务态度评分")
+    private Double serviceAttitudeRating;
+
+    @ApiModelProperty(value = "响应时间评分")
+    private Double responseTimeRating;
+
+    @ApiModelProperty(value = "专业能力评分")
+    private Double professionalAbilityRating;
+
+    @ApiModelProperty(value = "评价内容")
+    private String reviewContent;
+
+    @ApiModelProperty(value = "评价图片列表")
+    private List<String> reviewImages;
+
+    @ApiModelProperty(value = "是否匿名评价,0:否,1:是")
+    private Integer isAnonymous;
+
+    @ApiModelProperty(value = "点赞数")
+    private Integer likeCount;
+
+    @ApiModelProperty(value = "评论数")
+    private Integer commentCount;
+
+    @ApiModelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+}
+

+ 52 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/ReviewCommentVo.java

@@ -0,0 +1,52 @@
+package shop.alien.entity.store.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 评价评论VO
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Data
+@ApiModel(value = "ReviewCommentVo对象", description = "评价评论VO")
+public class ReviewCommentVo {
+
+    @ApiModelProperty(value = "主键")
+    private Integer id;
+
+    @ApiModelProperty(value = "评价ID")
+    private Integer reviewId;
+
+    @ApiModelProperty(value = "评论用户ID")
+    private Integer userId;
+
+    @ApiModelProperty(value = "评论用户名称")
+    private String userName;
+
+    @ApiModelProperty(value = "评论用户头像")
+    private String userAvatar;
+
+    @ApiModelProperty(value = "评论内容")
+    private String commentContent;
+
+    @ApiModelProperty(value = "点赞数")
+    private Integer likeCount;
+
+    @ApiModelProperty(value = "回复数")
+    private Integer replyCount;
+
+    @ApiModelProperty(value = "回复列表")
+    private List<CommentReplyVo> replies;
+
+    @ApiModelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+}
+

+ 44 - 0
alien-entity/src/main/java/shop/alien/mapper/CommentReplyMapper.java

@@ -0,0 +1,44 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import shop.alien.entity.store.CommentReply;
+import shop.alien.entity.store.vo.CommentReplyVo;
+
+import java.util.List;
+
+/**
+ * 评论回复 Mapper 接口
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Mapper
+public interface CommentReplyMapper extends BaseMapper<CommentReply> {
+
+    /**
+     * 根据评论ID查询回复列表(包含用户信息)
+     *
+     * @param commentId 评论ID
+     * @return 回复列表
+     */
+    List<CommentReplyVo> getReplyListByCommentId(@Param("commentId") Integer commentId);
+
+    /**
+     * 根据评论ID查询回复数量
+     *
+     * @param commentId 评论ID
+     * @return 回复数量
+     */
+    Integer getReplyCountByCommentId(@Param("commentId") Integer commentId);
+
+    /**
+     * 根据评论ID删除所有回复(逻辑删除)
+     *
+     * @param commentId 评论ID
+     * @return 删除数量
+     */
+    Integer deleteRepliesByCommentId(@Param("commentId") Integer commentId);
+}
+

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

@@ -0,0 +1,54 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import shop.alien.entity.store.OrderReview;
+import shop.alien.entity.store.vo.OrderReviewVo;
+
+import java.util.List;
+
+/**
+ * 订单评价 Mapper 接口
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Mapper
+public interface OrderReviewMapper extends BaseMapper<OrderReview> {
+
+    /**
+     * 分页查询评价列表(包含用户和律师信息)
+     *
+     * @param page 分页对象
+     * @param orderId 订单ID
+     * @param lawyerUserId 律师用户ID
+     * @param userId 评价用户ID
+     * @return 分页结果
+     */
+    IPage<OrderReviewVo> getReviewListWithUser(
+            IPage<OrderReviewVo> page,
+            @Param("orderId") Integer orderId,
+            @Param("lawyerUserId") Integer lawyerUserId,
+            @Param("userId") Integer userId
+    );
+
+    /**
+     * 根据订单ID查询评价
+     *
+     * @param orderId 订单ID
+     * @return 评价信息
+     */
+    OrderReviewVo getReviewByOrderId(@Param("orderId") Integer orderId);
+
+    /**
+     * 根据评价ID查询评价详情(包含用户和律师信息)
+     *
+     * @param reviewId 评价ID
+     * @return 评价详情
+     */
+    OrderReviewVo getReviewDetailById(@Param("reviewId") Integer reviewId);
+}
+

+ 36 - 0
alien-entity/src/main/java/shop/alien/mapper/ReviewCommentMapper.java

@@ -0,0 +1,36 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import shop.alien.entity.store.ReviewComment;
+import shop.alien.entity.store.vo.ReviewCommentVo;
+
+import java.util.List;
+
+/**
+ * 评价评论 Mapper 接口
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Mapper
+public interface ReviewCommentMapper extends BaseMapper<ReviewComment> {
+
+    /**
+     * 根据评价ID查询评论列表(包含用户信息)
+     *
+     * @param reviewId 评价ID
+     * @return 评论列表
+     */
+    List<ReviewCommentVo> getCommentListByReviewId(@Param("reviewId") Integer reviewId);
+
+    /**
+     * 根据评价ID查询评论数量
+     *
+     * @param reviewId 评价ID
+     * @return 评论数量
+     */
+    Integer getCommentCountByReviewId(@Param("reviewId") Integer reviewId);
+}
+

+ 60 - 0
alien-entity/src/main/resources/mapper/CommentReplyMapper.xml

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="shop.alien.mapper.CommentReplyMapper">
+
+    <!-- 回复列表查询结果映射 -->
+    <resultMap id="CommentReplyVoResultMap" type="shop.alien.entity.store.vo.CommentReplyVo">
+        <id column="id" property="id" />
+        <result column="comment_id" property="commentId" />
+        <result column="user_id" property="userId" />
+        <result column="user_name" property="userName" />
+        <result column="user_avatar" property="userAvatar" />
+        <result column="reply_to_user_id" property="replyToUserId" />
+        <result column="reply_to_user_name" property="replyToUserName" />
+        <result column="parent_reply_id" property="parentReplyId" />
+        <result column="reply_content" property="replyContent" />
+        <result column="like_count" property="likeCount" />
+        <result column="created_time" property="createdTime" />
+    </resultMap>
+
+    <!-- 根据评论ID查询回复列表(包含用户信息) -->
+    <select id="getReplyListByCommentId" resultMap="CommentReplyVoResultMap">
+        SELECT
+            cr.id,
+            cr.comment_id,
+            cr.user_id,
+            lu.user_name AS user_name,
+            lu.user_image AS user_avatar,
+            cr.reply_to_user_id,
+            lu2.user_name AS reply_to_user_name,
+            cr.parent_reply_id,
+            cr.reply_content,
+            cr.like_count,
+            cr.created_time
+        FROM comment_reply cr
+        LEFT JOIN life_user lu ON lu.id = cr.user_id AND lu.delete_flag = 0
+        LEFT JOIN life_user lu2 ON lu2.id = cr.reply_to_user_id AND lu2.delete_flag = 0
+        WHERE cr.delete_flag = 0
+        AND cr.comment_id = #{commentId}
+        ORDER BY cr.created_time ASC
+    </select>
+
+    <!-- 根据评论ID查询回复数量 -->
+    <select id="getReplyCountByCommentId" resultType="java.lang.Integer">
+        SELECT COUNT(*)
+        FROM comment_reply
+        WHERE delete_flag = 0
+        AND comment_id = #{commentId}
+    </select>
+
+    <!-- 根据评论ID删除所有回复(逻辑删除) -->
+    <update id="deleteRepliesByCommentId">
+        UPDATE comment_reply
+        SET delete_flag = 1,
+            updated_time = NOW()
+        WHERE delete_flag = 0
+        AND comment_id = #{commentId}
+    </update>
+
+</mapper>
+

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

@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="shop.alien.mapper.OrderReviewMapper">
+
+    <!-- 评价列表查询结果映射 -->
+    <resultMap id="OrderReviewVoResultMap" type="shop.alien.entity.store.vo.OrderReviewVo">
+        <id column="id" property="id" />
+        <result column="order_id" property="orderId" />
+        <result column="order_number" property="orderNumber" />
+        <result column="user_id" property="userId" />
+        <result column="user_name" property="userName" />
+        <result column="user_avatar" property="userAvatar" />
+        <result column="lawyer_user_id" property="lawyerUserId" />
+        <result column="lawyer_name" property="lawyerName" />
+        <result column="lawyer_avatar" property="lawyerAvatar" />
+        <result column="law_firm_name" property="lawFirmName" />
+        <result column="overall_rating" property="overallRating" />
+        <result column="service_attitude_rating" property="serviceAttitudeRating" />
+        <result column="response_time_rating" property="responseTimeRating" />
+        <result column="professional_ability_rating" property="professionalAbilityRating" />
+        <result column="review_content" property="reviewContent" />
+        <result column="is_anonymous" property="isAnonymous" />
+        <result column="like_count" property="likeCount" />
+        <result column="comment_count" property="commentCount" />
+        <result column="created_time" property="createdTime" />
+    </resultMap>
+
+    <!-- 分页查询评价列表(包含用户和律师信息) -->
+    <select id="getReviewListWithUser" resultMap="OrderReviewVoResultMap">
+        SELECT
+            orv.id,
+            orv.order_id,
+            orv.order_number,
+            orv.user_id,
+            CASE 
+                WHEN orv.is_anonymous = 1 THEN '匿名用户'
+                ELSE lu.user_name
+            END AS user_name,
+            CASE 
+                WHEN orv.is_anonymous = 1 THEN NULL
+                ELSE lu.user_image
+            END AS user_avatar,
+            orv.lawyer_user_id,
+            lu2.name AS lawyer_name,
+            lu2.head_img AS lawyer_avatar,
+            lf.firm_name AS law_firm_name,
+            orv.overall_rating,
+            orv.service_attitude_rating,
+            orv.response_time_rating,
+            orv.professional_ability_rating,
+            orv.review_content,
+            orv.is_anonymous,
+            orv.like_count,
+            orv.comment_count,
+            orv.created_time
+        FROM order_review orv
+        LEFT JOIN life_user lu ON lu.id = orv.user_id AND lu.delete_flag = 0
+        LEFT JOIN lawyer_user lu2 ON lu2.id = orv.lawyer_user_id AND lu2.delete_flag = 0
+        LEFT JOIN law_firm lf ON lf.id = lu2.firm_id AND lf.delete_flag = 0
+        WHERE orv.delete_flag = 0
+        <if test="orderId != null">
+            AND orv.order_id = #{orderId}
+        </if>
+        <if test="lawyerUserId != null">
+            AND orv.lawyer_user_id = #{lawyerUserId}
+        </if>
+        <if test="userId != null">
+            AND orv.user_id = #{userId}
+        </if>
+        ORDER BY orv.created_time DESC
+    </select>
+
+    <!-- 根据订单ID查询评价 -->
+    <select id="getReviewByOrderId" resultMap="OrderReviewVoResultMap">
+        SELECT
+            orv.id,
+            orv.order_id,
+            orv.order_number,
+            orv.user_id,
+            CASE 
+                WHEN orv.is_anonymous = 1 THEN '匿名用户'
+                ELSE lu.user_name
+            END AS user_name,
+            CASE 
+                WHEN orv.is_anonymous = 1 THEN NULL
+                ELSE lu.user_image
+            END AS user_avatar,
+            orv.lawyer_user_id,
+            lu2.name AS lawyer_name,
+            lu2.head_img AS lawyer_avatar,
+            lf.firm_name AS law_firm_name,
+            orv.overall_rating,
+            orv.service_attitude_rating,
+            orv.response_time_rating,
+            orv.professional_ability_rating,
+            orv.review_content,
+            orv.is_anonymous,
+            orv.like_count,
+            orv.comment_count,
+            orv.created_time
+        FROM order_review orv
+        LEFT JOIN life_user lu ON lu.id = orv.user_id AND lu.delete_flag = 0
+        LEFT JOIN lawyer_user lu2 ON lu2.id = orv.lawyer_user_id AND lu2.delete_flag = 0
+        LEFT JOIN law_firm lf ON lf.id = lu2.firm_id AND lf.delete_flag = 0
+        WHERE orv.delete_flag = 0
+        AND orv.order_id = #{orderId}
+        LIMIT 1
+    </select>
+
+    <!-- 根据评价ID查询评价详情(包含用户和律师信息) -->
+    <select id="getReviewDetailById" resultMap="OrderReviewVoResultMap">
+        SELECT
+            orv.id,
+            orv.order_id,
+            orv.order_number,
+            orv.user_id,
+            CASE 
+                WHEN orv.is_anonymous = 1 THEN '匿名用户'
+                ELSE lu.user_name
+            END AS user_name,
+            CASE 
+                WHEN orv.is_anonymous = 1 THEN NULL
+                ELSE lu.user_image
+            END AS user_avatar,
+            orv.lawyer_user_id,
+            lu2.name AS lawyer_name,
+            lu2.head_img AS lawyer_avatar,
+            lf.firm_name AS law_firm_name,
+            orv.overall_rating,
+            orv.service_attitude_rating,
+            orv.response_time_rating,
+            orv.professional_ability_rating,
+            orv.review_content,
+            orv.is_anonymous,
+            orv.like_count,
+            orv.comment_count,
+            orv.created_time
+        FROM order_review orv
+        LEFT JOIN life_user lu ON lu.id = orv.user_id AND lu.delete_flag = 0
+        LEFT JOIN lawyer_user lu2 ON lu2.id = orv.lawyer_user_id AND lu2.delete_flag = 0
+        LEFT JOIN law_firm lf ON lf.id = lu2.firm_id AND lf.delete_flag = 0
+        WHERE orv.delete_flag = 0
+        AND orv.id = #{reviewId}
+    </select>
+
+</mapper>
+

+ 46 - 0
alien-entity/src/main/resources/mapper/ReviewCommentMapper.xml

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="shop.alien.mapper.ReviewCommentMapper">
+
+    <!-- 评论列表查询结果映射 -->
+    <resultMap id="ReviewCommentVoResultMap" type="shop.alien.entity.store.vo.ReviewCommentVo">
+        <id column="id" property="id" />
+        <result column="review_id" property="reviewId" />
+        <result column="user_id" property="userId" />
+        <result column="user_name" property="userName" />
+        <result column="user_avatar" property="userAvatar" />
+        <result column="comment_content" property="commentContent" />
+        <result column="like_count" property="likeCount" />
+        <result column="reply_count" property="replyCount" />
+        <result column="created_time" property="createdTime" />
+    </resultMap>
+
+    <!-- 根据评价ID查询评论列表(包含用户信息) -->
+    <select id="getCommentListByReviewId" resultMap="ReviewCommentVoResultMap">
+        SELECT
+            rc.id,
+            rc.review_id,
+            rc.user_id,
+            lu.user_name AS user_name,
+            lu.user_image AS user_avatar,
+            rc.comment_content,
+            rc.like_count,
+            rc.reply_count,
+            rc.created_time
+        FROM review_comment rc
+        LEFT JOIN life_user lu ON lu.id = rc.user_id AND lu.delete_flag = 0
+        WHERE rc.delete_flag = 0
+        AND rc.review_id = #{reviewId}
+        ORDER BY rc.created_time DESC
+    </select>
+
+    <!-- 根据评价ID查询评论数量 -->
+    <select id="getCommentCountByReviewId" resultType="java.lang.Integer">
+        SELECT COUNT(*)
+        FROM review_comment
+        WHERE delete_flag = 0
+        AND review_id = #{reviewId}
+    </select>
+
+</mapper>
+

+ 68 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/controller/CommentReplyController.java

@@ -0,0 +1,68 @@
+package shop.alien.lawyer.controller;
+
+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.CommentReply;
+import shop.alien.entity.store.dto.CommentReplyDto;
+import shop.alien.entity.store.vo.CommentReplyVo;
+import shop.alien.entity.store.UserLoginInfo;
+import shop.alien.lawyer.service.CommentReplyService;
+import shop.alien.util.common.TokenInfo;
+
+import java.util.List;
+
+/**
+ * 评论回复 前端控制器
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Api(tags = {"律师平台-评论回复"})
+@ApiSort(17)
+@CrossOrigin
+@RestController
+@RequestMapping("/lawyer/commentReply")
+@RequiredArgsConstructor
+public class CommentReplyController {
+
+    private final CommentReplyService commentReplyService;
+
+    @ApiOperation("创建回复(用户对评论的回复)")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/create")
+    public R<CommentReply> createReply(@RequestBody CommentReplyDto replyDto,
+                                       @TokenInfo UserLoginInfo userLoginInfo) {
+        log.info("CommentReplyController.createReply?replyDto={}, userLoginInfo={}", replyDto, userLoginInfo);
+        if (userLoginInfo == null) {
+            return R.fail("用户未登录");
+        }
+        return commentReplyService.createReply(replyDto, userLoginInfo.getUserId());
+    }
+
+    @ApiOperation("根据评论ID查询回复列表")
+    @ApiOperationSupport(order = 2)
+    @ApiImplicitParam(name = "commentId", value = "评论ID", dataType = "int", paramType = "path", required = true)
+    @GetMapping("/list/{commentId}")
+    public R<List<CommentReplyVo>> getReplyListByCommentId(@PathVariable Integer commentId) {
+        log.info("CommentReplyController.getReplyListByCommentId?commentId={}", commentId);
+        return commentReplyService.getReplyListByCommentId(commentId);
+    }
+
+    @ApiOperation("删除回复")
+    @ApiOperationSupport(order = 3)
+    @ApiImplicitParam(name = "replyId", value = "回复ID", dataType = "int", paramType = "path", required = true)
+    @DeleteMapping("/delete/{replyId}")
+    public R<Boolean> deleteReply(@PathVariable Integer replyId,
+                                   @TokenInfo UserLoginInfo userLoginInfo) {
+        log.info("CommentReplyController.deleteReply?replyId={}, userLoginInfo={}", replyId, userLoginInfo);
+        if (userLoginInfo == null) {
+            return R.fail("用户未登录");
+        }
+        return commentReplyService.deleteReply(replyId, userLoginInfo.getUserId());
+    }
+}
+

+ 98 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/controller/OrderReviewController.java

@@ -0,0 +1,98 @@
+package shop.alien.lawyer.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+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.OrderReview;
+import shop.alien.entity.store.dto.OrderReviewDto;
+import shop.alien.entity.store.vo.OrderReviewDetailVo;
+import shop.alien.entity.store.vo.OrderReviewVo;
+import shop.alien.entity.store.UserLoginInfo;
+import shop.alien.lawyer.service.OrderReviewService;
+import shop.alien.util.common.TokenInfo;
+
+/**
+ * 订单评价 前端控制器
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Api(tags = {"律师平台-订单评价"})
+@ApiSort(15)
+@CrossOrigin
+@RestController
+@RequestMapping("/lawyer/orderReview")
+@RequiredArgsConstructor
+public class OrderReviewController {
+
+    private final OrderReviewService orderReviewService;
+
+    @ApiOperation("创建订单评价(只有订单用户才能评价)")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/create")
+    public R<OrderReview> createReview(@RequestBody OrderReviewDto reviewDto,
+                                        @TokenInfo UserLoginInfo userLoginInfo) {
+        log.info("OrderReviewController.createReview?reviewDto={}, userLoginInfo={}", reviewDto, userLoginInfo);
+        if (userLoginInfo == null) {
+            return R.fail("用户未登录");
+        }
+        return orderReviewService.createReview(reviewDto, userLoginInfo.getUserId());
+    }
+
+    @ApiOperation("分页查询评价列表")
+    @ApiOperationSupport(order = 2)
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "page", value = "页数(默认1)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "size", value = "页容(默认10)", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "orderId", value = "订单ID", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "lawyerUserId", value = "律师用户ID", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "userId", value = "评价用户ID", dataType = "int", paramType = "query")
+    })
+    @GetMapping("/list")
+    public R<IPage<OrderReviewVo>> getReviewList(
+            @RequestParam(defaultValue = "1") int page,
+            @RequestParam(defaultValue = "10") int size,
+            @RequestParam(required = false) Integer orderId,
+            @RequestParam(required = false) Integer lawyerUserId,
+            @RequestParam(required = false) Integer userId) {
+        log.info("OrderReviewController.getReviewList?page={}, size={}, orderId={}, lawyerUserId={}, userId={}",
+                page, size, orderId, lawyerUserId, userId);
+        return orderReviewService.getReviewList(page, size, orderId, lawyerUserId, userId);
+    }
+
+    @ApiOperation("获取评价详情(包含评论和回复)")
+    @ApiOperationSupport(order = 3)
+    @ApiImplicitParam(name = "reviewId", value = "评价ID", dataType = "int", paramType = "path", required = true)
+    @GetMapping("/detail/{reviewId}")
+    public R<OrderReviewDetailVo> getReviewDetail(@PathVariable Integer reviewId) {
+        log.info("OrderReviewController.getReviewDetail?reviewId={}", reviewId);
+        return orderReviewService.getReviewDetail(reviewId);
+    }
+
+    @ApiOperation("删除评价(删除评价时,会级联删除该评价下的所有评论和回复)")
+    @ApiOperationSupport(order = 4)
+    @ApiImplicitParam(name = "reviewId", value = "评价ID", dataType = "int", paramType = "path", required = true)
+    @DeleteMapping("/delete/{reviewId}")
+    public R<Boolean> deleteReview(@PathVariable Integer reviewId,
+                                    @TokenInfo UserLoginInfo userLoginInfo) {
+        log.info("OrderReviewController.deleteReview?reviewId={}, userLoginInfo={}", reviewId, userLoginInfo);
+        if (userLoginInfo == null) {
+            return R.fail("用户未登录");
+        }
+        return orderReviewService.deleteReview(reviewId, userLoginInfo.getUserId());
+    }
+
+    @ApiOperation("根据订单ID查询评价")
+    @ApiOperationSupport(order = 5)
+    @ApiImplicitParam(name = "orderId", value = "订单ID", dataType = "int", paramType = "path", required = true)
+    @GetMapping("/order/{orderId}")
+    public R<OrderReviewVo> getReviewByOrderId(@PathVariable Integer orderId) {
+        log.info("OrderReviewController.getReviewByOrderId?orderId={}", orderId);
+        return orderReviewService.getReviewByOrderId(orderId);
+    }
+}
+

+ 68 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/controller/ReviewCommentController.java

@@ -0,0 +1,68 @@
+package shop.alien.lawyer.controller;
+
+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.ReviewComment;
+import shop.alien.entity.store.dto.ReviewCommentDto;
+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;
+
+/**
+ * 评价评论 前端控制器
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Api(tags = {"律师平台-评价评论"})
+@ApiSort(16)
+@CrossOrigin
+@RestController
+@RequestMapping("/lawyer/reviewComment")
+@RequiredArgsConstructor
+public class ReviewCommentController {
+
+    private final ReviewCommentService reviewCommentService;
+
+    @ApiOperation("创建评论(其他用户对评价的评论)")
+    @ApiOperationSupport(order = 1)
+    @PostMapping("/create")
+    public R<ReviewComment> createComment(@RequestBody ReviewCommentDto commentDto,
+                                          @TokenInfo UserLoginInfo userLoginInfo) {
+        log.info("ReviewCommentController.createComment?commentDto={}, userLoginInfo={}", commentDto, userLoginInfo);
+        if (userLoginInfo == null) {
+            return R.fail("用户未登录");
+        }
+        return reviewCommentService.createComment(commentDto, userLoginInfo.getUserId());
+    }
+
+    @ApiOperation("根据评价ID查询评论列表")
+    @ApiOperationSupport(order = 2)
+    @ApiImplicitParam(name = "reviewId", value = "评价ID", dataType = "int", paramType = "path", required = true)
+    @GetMapping("/list/{reviewId}")
+    public R<List<ReviewCommentVo>> getCommentListByReviewId(@PathVariable Integer reviewId) {
+        log.info("ReviewCommentController.getCommentListByReviewId?reviewId={}", reviewId);
+        return reviewCommentService.getCommentListByReviewId(reviewId);
+    }
+
+    @ApiOperation("删除评论(删除评论时,会级联删除该评论下的所有回复)")
+    @ApiOperationSupport(order = 3)
+    @ApiImplicitParam(name = "commentId", value = "评论ID", dataType = "int", paramType = "path", required = true)
+    @DeleteMapping("/delete/{commentId}")
+    public R<Boolean> deleteComment(@PathVariable Integer commentId,
+                                     @TokenInfo UserLoginInfo userLoginInfo) {
+        log.info("ReviewCommentController.deleteComment?commentId={}, userLoginInfo={}", commentId, userLoginInfo);
+        if (userLoginInfo == null) {
+            return R.fail("用户未登录");
+        }
+        return reviewCommentService.deleteComment(commentId, userLoginInfo.getUserId());
+    }
+}
+

+ 45 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/CommentReplyService.java

@@ -0,0 +1,45 @@
+package shop.alien.lawyer.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.CommentReply;
+import shop.alien.entity.store.dto.CommentReplyDto;
+import shop.alien.entity.store.vo.CommentReplyVo;
+
+import java.util.List;
+
+/**
+ * 评论回复 服务类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+public interface CommentReplyService extends IService<CommentReply> {
+
+    /**
+     * 创建回复(用户对评论的回复)
+     *
+     * @param replyDto 回复DTO
+     * @param userId 用户ID
+     * @return R<CommentReply>
+     */
+    R<CommentReply> createReply(CommentReplyDto replyDto, Integer userId);
+
+    /**
+     * 根据评论ID查询回复列表
+     *
+     * @param commentId 评论ID
+     * @return R<List<CommentReplyVo>>
+     */
+    R<List<CommentReplyVo>> getReplyListByCommentId(Integer commentId);
+
+    /**
+     * 删除回复
+     *
+     * @param replyId 回复ID
+     * @param userId 用户ID(验证是否为回复用户)
+     * @return R<Boolean>
+     */
+    R<Boolean> deleteReply(Integer replyId, Integer userId);
+}
+

+ 65 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/OrderReviewService.java

@@ -0,0 +1,65 @@
+package shop.alien.lawyer.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+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.OrderReviewDetailVo;
+import shop.alien.entity.store.vo.OrderReviewVo;
+
+/**
+ * 订单评价 服务类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+public interface OrderReviewService extends IService<OrderReview> {
+
+    /**
+     * 创建订单评价(只有订单用户才能评价)
+     *
+     * @param reviewDto 评价DTO
+     * @param userId 用户ID
+     * @return R<OrderReview>
+     */
+    R<OrderReview> createReview(OrderReviewDto reviewDto, Integer userId);
+
+    /**
+     * 分页查询评价列表
+     *
+     * @param pageNum 页码
+     * @param pageSize 页大小
+     * @param orderId 订单ID(可选)
+     * @param lawyerUserId 律师用户ID(可选)
+     * @param userId 评价用户ID(可选)
+     * @return R<IPage<OrderReviewVo>>
+     */
+    R<IPage<OrderReviewVo>> getReviewList(int pageNum, int pageSize, Integer orderId, Integer lawyerUserId, Integer userId);
+
+    /**
+     * 获取评价详情(包含评论和回复)
+     *
+     * @param reviewId 评价ID
+     * @return R<OrderReviewDetailVo>
+     */
+    R<OrderReviewDetailVo> getReviewDetail(Integer reviewId);
+
+    /**
+     * 删除评价(删除评价时,会级联删除该评价下的所有评论和回复)
+     *
+     * @param reviewId 评价ID
+     * @param userId 用户ID(验证是否为评价用户)
+     * @return R<Boolean>
+     */
+    R<Boolean> deleteReview(Integer reviewId, Integer userId);
+
+    /**
+     * 根据订单ID查询评价
+     *
+     * @param orderId 订单ID
+     * @return R<OrderReviewVo>
+     */
+    R<OrderReviewVo> getReviewByOrderId(Integer orderId);
+}
+

+ 45 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/ReviewCommentService.java

@@ -0,0 +1,45 @@
+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.vo.ReviewCommentVo;
+
+import java.util.List;
+
+/**
+ * 评价评论 服务类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+public interface ReviewCommentService extends IService<ReviewComment> {
+
+    /**
+     * 创建评论(其他用户对评价的评论)
+     *
+     * @param commentDto 评论DTO
+     * @param userId 用户ID
+     * @return R<ReviewComment>
+     */
+    R<ReviewComment> createComment(ReviewCommentDto commentDto, Integer userId);
+
+    /**
+     * 根据评价ID查询评论列表
+     *
+     * @param reviewId 评价ID
+     * @return R<List<ReviewCommentVo>>
+     */
+    R<List<ReviewCommentVo>> getCommentListByReviewId(Integer reviewId);
+
+    /**
+     * 删除评论(删除评论时,会级联删除该评论下的所有回复)
+     *
+     * @param commentId 评论ID
+     * @param userId 用户ID(验证是否为评论用户)
+     * @return R<Boolean>
+     */
+    R<Boolean> deleteComment(Integer commentId, Integer userId);
+}
+

+ 140 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/CommentReplyServiceImpl.java

@@ -0,0 +1,140 @@
+package shop.alien.lawyer.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.CommentReply;
+import shop.alien.entity.store.ReviewComment;
+import shop.alien.entity.store.dto.CommentReplyDto;
+import shop.alien.entity.store.vo.CommentReplyVo;
+import shop.alien.lawyer.service.CommentReplyService;
+import shop.alien.lawyer.service.ReviewCommentService;
+import shop.alien.mapper.CommentReplyMapper;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 评论回复 服务实现类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Transactional
+@Service
+@RequiredArgsConstructor
+public class CommentReplyServiceImpl extends ServiceImpl<CommentReplyMapper, CommentReply> implements CommentReplyService {
+
+    private final CommentReplyMapper commentReplyMapper;
+    private final ReviewCommentService reviewCommentService;
+
+    @Override
+    public R<CommentReply> createReply(CommentReplyDto replyDto, Integer userId) {
+        log.info("CommentReplyServiceImpl.createReply?replyDto={}, userId={}", replyDto, userId);
+
+        // 参数校验
+        if (replyDto == null) {
+            return R.fail("回复信息不能为空");
+        }
+        if (replyDto.getCommentId() == null) {
+            return R.fail("评论ID不能为空");
+        }
+        if (replyDto.getReplyContent() == null || replyDto.getReplyContent().trim().isEmpty()) {
+            return R.fail("回复内容不能为空");
+        }
+        if (userId == null) {
+            return R.fail("用户ID不能为空");
+        }
+
+        // 验证评论是否存在
+        ReviewComment comment = reviewCommentService.getById(replyDto.getCommentId());
+        if (comment == null || comment.getDeleteFlag() == 1) {
+            return R.fail("评论不存在或已删除");
+        }
+
+        // 创建回复
+        CommentReply reply = new CommentReply();
+        reply.setCommentId(replyDto.getCommentId());
+        reply.setUserId(userId);
+        reply.setReplyToUserId(replyDto.getReplyToUserId());
+        reply.setParentReplyId(replyDto.getParentReplyId() != null ? replyDto.getParentReplyId() : 0);
+        reply.setReplyContent(replyDto.getReplyContent());
+        reply.setLikeCount(0);
+        reply.setCreatedUserId(userId);
+        reply.setCreatedTime(new Date());
+
+        boolean success = this.save(reply);
+        if (success) {
+            // 更新评论的回复数
+            comment.setReplyCount((comment.getReplyCount() == null ? 0 : comment.getReplyCount()) + 1);
+            reviewCommentService.updateById(comment);
+            
+            log.info("创建回复成功,回复ID={}", reply.getId());
+            return R.data(reply, "回复成功");
+        } else {
+            log.error("创建回复失败");
+            return R.fail("创建回复失败");
+        }
+    }
+
+    @Override
+    public R<List<CommentReplyVo>> getReplyListByCommentId(Integer commentId) {
+        log.info("CommentReplyServiceImpl.getReplyListByCommentId?commentId={}", commentId);
+
+        if (commentId == null) {
+            return R.fail("评论ID不能为空");
+        }
+
+        List<CommentReplyVo> replies = commentReplyMapper.getReplyListByCommentId(commentId);
+        return R.data(replies);
+    }
+
+    @Override
+    public R<Boolean> deleteReply(Integer replyId, Integer userId) {
+        log.info("CommentReplyServiceImpl.deleteReply?replyId={}, userId={}", replyId, userId);
+
+        if (replyId == null) {
+            return R.fail("回复ID不能为空");
+        }
+        if (userId == null) {
+            return R.fail("用户ID不能为空");
+        }
+
+        // 查询回复
+        CommentReply reply = this.getById(replyId);
+        if (reply == null) {
+            return R.fail("回复不存在");
+        }
+
+        // 验证是否为回复用户
+        if (!reply.getUserId().equals(userId)) {
+            return R.fail("只能删除自己的回复");
+        }
+
+        // 删除回复(逻辑删除)
+        reply.setDeleteFlag(1);
+        reply.setUpdatedUserId(userId);
+        reply.setUpdatedTime(new Date());
+        boolean success = this.updateById(reply);
+
+        if (success) {
+            // 更新评论的回复数
+            ReviewComment comment = reviewCommentService.getById(reply.getCommentId());
+            if (comment != null) {
+                comment.setReplyCount((comment.getReplyCount() == null ? 0 : comment.getReplyCount()) - 1);
+                reviewCommentService.updateById(comment);
+            }
+            
+            log.info("删除回复成功,回复ID={}", replyId);
+            return R.data(true, "删除成功");
+        } else {
+            log.error("删除回复失败,回复ID={}", replyId);
+            return R.fail("删除回复失败");
+        }
+    }
+}
+

+ 257 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/OrderReviewServiceImpl.java

@@ -0,0 +1,257 @@
+package shop.alien.lawyer.service.impl;
+
+import com.alibaba.fastjson2.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LawyerConsultationOrder;
+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.OrderReviewDetailVo;
+import shop.alien.entity.store.vo.OrderReviewVo;
+import shop.alien.lawyer.service.OrderReviewService;
+import shop.alien.lawyer.service.ReviewCommentService;
+import shop.alien.mapper.*;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 订单评价 服务实现类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Transactional
+@Service
+@RequiredArgsConstructor
+public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, OrderReview> implements OrderReviewService {
+
+    private final OrderReviewMapper orderReviewMapper;
+    private final LawyerConsultationOrderMapper lawyerConsultationOrderMapper;
+    private final ReviewCommentService reviewCommentService;
+    private final ReviewCommentMapper reviewCommentMapper;
+    private final CommentReplyMapper commentReplyMapper;
+
+    @Override
+    public R<OrderReview> createReview(OrderReviewDto reviewDto, Integer userId) {
+        log.info("OrderReviewServiceImpl.createReview?reviewDto={}, userId={}", reviewDto, userId);
+
+        // 参数校验
+        if (reviewDto == null) {
+            return R.fail("评价信息不能为空");
+        }
+        if (reviewDto.getOrderId() == null) {
+            return R.fail("订单ID不能为空");
+        }
+        if (userId == null) {
+            return R.fail("用户ID不能为空");
+        }
+
+        // 验证订单是否存在且属于该用户
+        LawyerConsultationOrder order = lawyerConsultationOrderMapper.selectById(reviewDto.getOrderId());
+        if (order == null) {
+            return R.fail("订单不存在");
+        }
+        if (!order.getClientUserId().equals(userId)) {
+            return R.fail("只能评价自己的订单");
+        }
+
+        // 检查订单是否已完成
+        if (order.getOrderStatus() == null || order.getOrderStatus() != 3) {
+            return R.fail("只能对已完成的订单进行评价");
+        }
+
+        // 检查是否已经评价过
+        LambdaQueryWrapper<OrderReview> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(OrderReview::getOrderId, reviewDto.getOrderId())
+                .eq(OrderReview::getDeleteFlag, 0);
+        OrderReview existingReview = this.getOne(queryWrapper);
+        if (existingReview != null) {
+            return R.fail("该订单已经评价过了");
+        }
+
+        // 创建评价
+        OrderReview review = new OrderReview();
+        review.setOrderId(reviewDto.getOrderId());
+        review.setOrderNumber(reviewDto.getOrderNumber());
+        review.setUserId(userId);
+        review.setLawyerUserId(order.getLawyerUserId());
+        review.setOverallRating(reviewDto.getOverallRating());
+        review.setServiceAttitudeRating(reviewDto.getServiceAttitudeRating());
+        review.setResponseTimeRating(reviewDto.getResponseTimeRating());
+        review.setProfessionalAbilityRating(reviewDto.getProfessionalAbilityRating());
+        review.setReviewContent(reviewDto.getReviewContent());
+        
+        // 处理评价图片
+        if (reviewDto.getReviewImages() != null && !reviewDto.getReviewImages().isEmpty()) {
+            review.setReviewImages(JSON.toJSONString(reviewDto.getReviewImages()));
+        }
+        
+        review.setIsAnonymous(reviewDto.getIsAnonymous() != null ? reviewDto.getIsAnonymous() : 0);
+        review.setLikeCount(0);
+        review.setCommentCount(0);
+        review.setCreatedUserId(userId);
+        review.setCreatedTime(new Date());
+
+        boolean success = this.save(review);
+        if (success) {
+            log.info("创建评价成功,评价ID={}", review.getId());
+            return R.data(review, "评价成功");
+        } else {
+            log.error("创建评价失败");
+            return R.fail("创建评价失败");
+        }
+    }
+
+    @Override
+    public R<IPage<OrderReviewVo>> getReviewList(int pageNum, int pageSize, Integer orderId, Integer lawyerUserId, Integer userId) {
+        log.info("OrderReviewServiceImpl.getReviewList?pageNum={}, pageSize={}, orderId={}, lawyerUserId={}, userId={}",
+                pageNum, pageSize, orderId, lawyerUserId, userId);
+
+        Page<OrderReviewVo> page = new Page<>(pageNum, pageSize);
+        IPage<OrderReviewVo> result = orderReviewMapper.getReviewListWithUser(page, orderId, lawyerUserId, userId);
+        
+        // 处理评价图片JSON字符串转换为列表
+        if (result.getRecords() != null) {
+            for (OrderReviewVo vo : result.getRecords()) {
+                if (vo.getReviewImages() != null && !vo.getReviewImages().isEmpty()) {
+                    // 如果已经是列表,则不需要转换
+                    // 这里假设VO中的reviewImages已经是List<String>类型
+                }
+            }
+        }
+
+        return R.data(result);
+    }
+
+    @Override
+    public R<OrderReviewDetailVo> getReviewDetail(Integer reviewId) {
+        log.info("OrderReviewServiceImpl.getReviewDetail?reviewId={}", reviewId);
+
+        if (reviewId == null) {
+            return R.fail("评价ID不能为空");
+        }
+
+        // 查询评价详情
+        OrderReviewVo reviewVo = orderReviewMapper.getReviewDetailById(reviewId);
+        if (reviewVo == null) {
+            return R.fail("评价不存在");
+        }
+
+        // 处理评价图片
+        OrderReview review = this.getById(reviewId);
+        if (review != null && review.getReviewImages() != null) {
+            try {
+                List<String> images = JSON.parseArray(review.getReviewImages(), String.class);
+                reviewVo.setReviewImages(images);
+            } catch (Exception e) {
+                log.warn("解析评价图片失败:{}", e.getMessage());
+            }
+        }
+
+        // 查询评论列表
+        List<shop.alien.entity.store.vo.ReviewCommentVo> comments = reviewCommentMapper.getCommentListByReviewId(reviewId);
+        
+        // 构建返回结果
+        OrderReviewDetailVo detailVo = new OrderReviewDetailVo();
+        detailVo.setReview(reviewVo);
+        detailVo.setComments(comments);
+        detailVo.setTotalCommentCount(comments != null ? comments.size() : 0);
+
+        return R.data(detailVo);
+    }
+
+    @Override
+    public R<Boolean> deleteReview(Integer reviewId, Integer userId) {
+        log.info("OrderReviewServiceImpl.deleteReview?reviewId={}, userId={}", reviewId, userId);
+
+        if (reviewId == null) {
+            return R.fail("评价ID不能为空");
+        }
+        if (userId == null) {
+            return R.fail("用户ID不能为空");
+        }
+
+        // 查询评价
+        OrderReview review = this.getById(reviewId);
+        if (review == null) {
+            return R.fail("评价不存在");
+        }
+
+        // 验证是否为评价用户
+        if (!review.getUserId().equals(userId)) {
+            return R.fail("只能删除自己的评价");
+        }
+
+        // 查询该评价下的所有评论
+        LambdaQueryWrapper<ReviewComment> commentWrapper = new LambdaQueryWrapper<>();
+        commentWrapper.eq(ReviewComment::getReviewId, reviewId)
+                .eq(ReviewComment::getDeleteFlag, 0);
+        List<ReviewComment> comments = reviewCommentService.list(commentWrapper);
+
+        // 删除评价(逻辑删除)
+        review.setDeleteFlag(1);
+        review.setUpdatedUserId(userId);
+        review.setUpdatedTime(new Date());
+        boolean success = this.updateById(review);
+
+        if (success) {
+            // 级联删除该评价下的所有评论和回复
+            for (ReviewComment comment : comments) {
+                // 删除评论下的所有回复
+                commentReplyMapper.deleteRepliesByCommentId(comment.getId());
+                
+                // 删除评论
+                comment.setDeleteFlag(1);
+                comment.setUpdatedUserId(userId);
+                comment.setUpdatedTime(new Date());
+                reviewCommentService.updateById(comment);
+            }
+            
+            log.info("删除评价成功,评价ID={}", reviewId);
+            return R.data(true, "删除成功");
+        } else {
+            log.error("删除评价失败,评价ID={}", reviewId);
+            return R.fail("删除评价失败");
+        }
+    }
+
+    @Override
+    public R<OrderReviewVo> getReviewByOrderId(Integer orderId) {
+        log.info("OrderReviewServiceImpl.getReviewByOrderId?orderId={}", orderId);
+
+        if (orderId == null) {
+            return R.fail("订单ID不能为空");
+        }
+
+        OrderReviewVo reviewVo = orderReviewMapper.getReviewByOrderId(orderId);
+        if (reviewVo == null) {
+            return R.fail("该订单暂无评价");
+        }
+
+        // 处理评价图片
+        OrderReview review = this.getOne(new LambdaQueryWrapper<OrderReview>()
+                .eq(OrderReview::getOrderId, orderId)
+                .eq(OrderReview::getDeleteFlag, 0));
+        if (review != null && review.getReviewImages() != null) {
+            try {
+                List<String> images = JSON.parseArray(review.getReviewImages(), String.class);
+                reviewVo.setReviewImages(images);
+            } catch (Exception e) {
+                log.warn("解析评价图片失败:{}", e.getMessage());
+            }
+        }
+
+        return R.data(reviewVo);
+    }
+}
+

+ 151 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/ReviewCommentServiceImpl.java

@@ -0,0 +1,151 @@
+package shop.alien.lawyer.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.OrderReview;
+import shop.alien.entity.store.ReviewComment;
+import shop.alien.entity.store.dto.ReviewCommentDto;
+import shop.alien.entity.store.vo.ReviewCommentVo;
+import shop.alien.lawyer.service.OrderReviewService;
+import shop.alien.lawyer.service.ReviewCommentService;
+import shop.alien.mapper.CommentReplyMapper;
+import shop.alien.mapper.ReviewCommentMapper;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 评价评论 服务实现类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+@Slf4j
+@Transactional
+@Service
+public class ReviewCommentServiceImpl extends ServiceImpl<ReviewCommentMapper, ReviewComment> implements ReviewCommentService {
+
+    private final ReviewCommentMapper reviewCommentMapper;
+    private final CommentReplyMapper commentReplyMapper;
+    private final OrderReviewService orderReviewService;
+
+    public ReviewCommentServiceImpl(ReviewCommentMapper reviewCommentMapper,
+                                    CommentReplyMapper commentReplyMapper,
+                                    @Lazy OrderReviewService orderReviewService) {
+        this.reviewCommentMapper = reviewCommentMapper;
+        this.commentReplyMapper = commentReplyMapper;
+        this.orderReviewService = orderReviewService;
+    }
+
+    @Override
+    public R<ReviewComment> createComment(ReviewCommentDto commentDto, Integer userId) {
+        log.info("ReviewCommentServiceImpl.createComment?commentDto={}, userId={}", commentDto, userId);
+
+        // 参数校验
+        if (commentDto == null) {
+            return R.fail("评论信息不能为空");
+        }
+        if (commentDto.getReviewId() == null) {
+            return R.fail("评价ID不能为空");
+        }
+        if (commentDto.getCommentContent() == null || commentDto.getCommentContent().trim().isEmpty()) {
+            return R.fail("评论内容不能为空");
+        }
+        if (userId == null) {
+            return R.fail("用户ID不能为空");
+        }
+
+        // 验证评价是否存在
+        OrderReview review = orderReviewService.getById(commentDto.getReviewId());
+        if (review == null || review.getDeleteFlag() == 1) {
+            return R.fail("评价不存在或已删除");
+        }
+
+        // 创建评论
+        ReviewComment comment = new ReviewComment();
+        comment.setReviewId(commentDto.getReviewId());
+        comment.setUserId(userId);
+        comment.setCommentContent(commentDto.getCommentContent());
+        comment.setLikeCount(0);
+        comment.setReplyCount(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.getId());
+            return R.data(comment, "评论成功");
+        } else {
+            log.error("创建评论失败");
+            return R.fail("创建评论失败");
+        }
+    }
+
+    @Override
+    public R<List<ReviewCommentVo>> getCommentListByReviewId(Integer reviewId) {
+        log.info("ReviewCommentServiceImpl.getCommentListByReviewId?reviewId={}", reviewId);
+
+        if (reviewId == null) {
+            return R.fail("评价ID不能为空");
+        }
+
+        List<ReviewCommentVo> comments = reviewCommentMapper.getCommentListByReviewId(reviewId);
+        return R.data(comments);
+    }
+
+    @Override
+    public R<Boolean> deleteComment(Integer commentId, Integer userId) {
+        log.info("ReviewCommentServiceImpl.deleteComment?commentId={}, userId={}", commentId, userId);
+
+        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.getUserId().equals(userId)) {
+            return R.fail("只能删除自己的评论");
+        }
+
+        // 删除评论下的所有回复
+        commentReplyMapper.deleteRepliesByCommentId(commentId);
+
+        // 删除评论(逻辑删除)
+        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("删除评论失败");
+        }
+    }
+}
+