|
|
@@ -11,6 +11,7 @@ import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
import shop.alien.entity.result.R;
|
|
|
import shop.alien.entity.store.LawyerConsultationOrder;
|
|
|
import shop.alien.entity.store.LifeLikeRecord;
|
|
|
@@ -22,7 +23,12 @@ import shop.alien.entity.store.vo.OrderReviewVo;
|
|
|
import shop.alien.entity.store.vo.PendingReviewVo;
|
|
|
import shop.alien.lawyer.service.OrderReviewService;
|
|
|
import shop.alien.lawyer.service.ReviewCommentService;
|
|
|
-import shop.alien.mapper.*;
|
|
|
+import shop.alien.entity.store.LawyerUser;
|
|
|
+import shop.alien.mapper.LawyerConsultationOrderMapper;
|
|
|
+import shop.alien.mapper.LawyerUserMapper;
|
|
|
+import shop.alien.mapper.LifeLikeRecordMapper;
|
|
|
+import shop.alien.mapper.OrderReviewMapper;
|
|
|
+import shop.alien.mapper.ReviewCommentMapper;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Date;
|
|
|
@@ -46,6 +52,7 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
|
|
|
private final ReviewCommentService reviewCommentService;
|
|
|
private final ReviewCommentMapper reviewCommentMapper;
|
|
|
private final LifeLikeRecordMapper lifeLikeRecordMapper;
|
|
|
+ private final LawyerUserMapper lawyerUserMapper;
|
|
|
|
|
|
@Override
|
|
|
public R<OrderReview> createReview(OrderReviewDto reviewDto) {
|
|
|
@@ -119,6 +126,8 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
|
|
|
boolean success = this.save(review);
|
|
|
if (success) {
|
|
|
log.info("创建评价成功,评价ID={}", review.getId());
|
|
|
+ // 更新律师评分
|
|
|
+ updateLawyerServiceScore(review.getLawyerUserId());
|
|
|
return R.data(review, "评价成功");
|
|
|
} else {
|
|
|
log.error("创建评价失败");
|
|
|
@@ -126,6 +135,71 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 更新律师服务评分和好评/中评/差评数量
|
|
|
+ * 计算公式:律师评分 = overallRating平均值 (转换为0-5分)
|
|
|
+ * 评分规则:0-2.5分=差评,3-4分=中评,4.5-5分=好评
|
|
|
+ *
|
|
|
+ * @param lawyerUserId 律师用户ID
|
|
|
+ */
|
|
|
+ private void updateLawyerServiceScore(Integer lawyerUserId) {
|
|
|
+ if (lawyerUserId == null) {
|
|
|
+ log.warn("更新律师评分失败:律师ID为空");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 计算平均评分(1-5星)
|
|
|
+ Double averageRating = orderReviewMapper.getAverageRatingByLawyerUserId(lawyerUserId);
|
|
|
+
|
|
|
+ Integer serviceScore;
|
|
|
+ if (averageRating != null) {
|
|
|
+ // 转换为0-5分:service_score = averageRating(四舍五入)
|
|
|
+ serviceScore = (int) Math.round(averageRating);
|
|
|
+ // 确保在0-5范围内
|
|
|
+ serviceScore = Math.max(0, Math.min(5, serviceScore));
|
|
|
+ } else {
|
|
|
+ // 如果没有评价,设置为0
|
|
|
+ serviceScore = 0;
|
|
|
+ log.info("律师暂无评价,将评分设置为0,律师ID={}", lawyerUserId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 统计好评、中评、差评数量
|
|
|
+ Integer goodReviewCount = orderReviewMapper.getGoodReviewCountByLawyerUserId(lawyerUserId);
|
|
|
+ Integer mediumReviewCount = orderReviewMapper.getMediumReviewCountByLawyerUserId(lawyerUserId);
|
|
|
+ Integer badReviewCount = orderReviewMapper.getBadReviewCountByLawyerUserId(lawyerUserId);
|
|
|
+
|
|
|
+ // 处理空值
|
|
|
+ if (goodReviewCount == null) {
|
|
|
+ goodReviewCount = 0;
|
|
|
+ }
|
|
|
+ if (mediumReviewCount == null) {
|
|
|
+ mediumReviewCount = 0;
|
|
|
+ }
|
|
|
+ if (badReviewCount == null) {
|
|
|
+ badReviewCount = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新律师评分和好评/中评/差评数量
|
|
|
+ LambdaUpdateWrapper<LawyerUser> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ updateWrapper.eq(LawyerUser::getId, lawyerUserId);
|
|
|
+ updateWrapper.set(LawyerUser::getServiceScore, serviceScore);
|
|
|
+ updateWrapper.set(LawyerUser::getGoodReviewCount, goodReviewCount);
|
|
|
+ updateWrapper.set(LawyerUser::getMediumReviewCount, mediumReviewCount);
|
|
|
+ updateWrapper.set(LawyerUser::getBadReviewCount, badReviewCount);
|
|
|
+ int result = lawyerUserMapper.update(null, updateWrapper);
|
|
|
+
|
|
|
+ if (result > 0) {
|
|
|
+ log.info("更新律师评分成功,律师ID={}, 平均评分={}, 服务评分={}, 好评数={}, 中评数={}, 差评数={}",
|
|
|
+ lawyerUserId, averageRating, serviceScore, goodReviewCount, mediumReviewCount, badReviewCount);
|
|
|
+ } else {
|
|
|
+ log.warn("更新律师评分失败,律师ID={}", lawyerUserId);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("更新律师评分异常,律师ID={}, 错误信息={}", lawyerUserId, e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public R<IPage<OrderReviewVo>> getReviewList(int pageNum, int pageSize, Integer orderId, Integer lawyerUserId, Integer userId, Integer currentUserId) {
|
|
|
log.info("OrderReviewServiceImpl.getReviewList?pageNum={}, pageSize={}, orderId={}, lawyerUserId={}, userId={}, currentUserId={}",
|
|
|
@@ -160,16 +234,19 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
|
|
|
if (reviewVo == null) {
|
|
|
return R.fail("评价不存在");
|
|
|
}
|
|
|
+ log.debug("查询评价详情,reviewId={}, currentUserId={}, isLiked={}", reviewId, currentUserId, reviewVo.getIsLiked());
|
|
|
|
|
|
- // 处理评价图片
|
|
|
- OrderReview review = this.getById(reviewId);
|
|
|
- if (review != null && review.getReviewImages() != null) {
|
|
|
+ // 处理评价图片:从SQL查询结果中解析JSON字符串
|
|
|
+ if (reviewVo.getReviewImagesJson() != null && !reviewVo.getReviewImagesJson().trim().isEmpty()) {
|
|
|
try {
|
|
|
- List<String> images = JSON.parseArray(review.getReviewImages(), String.class);
|
|
|
- reviewVo.setReviewImages(images);
|
|
|
+ List<String> images = JSON.parseArray(reviewVo.getReviewImagesJson(), String.class);
|
|
|
+ reviewVo.setReviewImages(images != null ? images : new ArrayList<>());
|
|
|
} catch (Exception e) {
|
|
|
log.warn("解析评价图片失败:{}", e.getMessage());
|
|
|
+ reviewVo.setReviewImages(new ArrayList<>());
|
|
|
}
|
|
|
+ } else {
|
|
|
+ reviewVo.setReviewImages(new ArrayList<>());
|
|
|
}
|
|
|
|
|
|
// 查询评论列表
|
|
|
@@ -183,14 +260,20 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 查询总评论数(包括首评论和子评论)
|
|
|
+ Integer totalCommentCount = reviewCommentMapper.getTotalCommentCountByReviewId(reviewId);
|
|
|
+ if (totalCommentCount == null) {
|
|
|
+ totalCommentCount = 0;
|
|
|
+ }
|
|
|
+
|
|
|
// 构建返回结果
|
|
|
OrderReviewDetailVo detailVo = new OrderReviewDetailVo();
|
|
|
detailVo.setReview(reviewVo);
|
|
|
- detailVo.setComments(comments);
|
|
|
- detailVo.setTotalCommentCount(comments != null ? comments.size() : 0);
|
|
|
+ detailVo.setComments(comments != null ? comments : new ArrayList<>());
|
|
|
+ detailVo.setTotalCommentCount(totalCommentCount);
|
|
|
// 设置评价的点赞数和是否已点赞(从 reviewVo 中获取)
|
|
|
- detailVo.setLikeCount(reviewVo.getLikeCount());
|
|
|
- detailVo.setIsLiked(reviewVo.getIsLiked());
|
|
|
+ detailVo.setLikeCount(reviewVo.getLikeCount() != null ? reviewVo.getLikeCount() : 0);
|
|
|
+ detailVo.setIsLiked(reviewVo.getIsLiked() != null ? reviewVo.getIsLiked() : 0);
|
|
|
|
|
|
return R.data(detailVo);
|
|
|
}
|
|
|
@@ -445,5 +528,38 @@ public class OrderReviewServiceImpl extends ServiceImpl<OrderReviewMapper, Order
|
|
|
return R.data(true, "未点赞");
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R<IPage<OrderReviewVo>> getReviewListByLawyerAndType(int pageNum, int pageSize, Integer lawyerUserId, Integer type, Integer currentUserId) {
|
|
|
+ log.info("OrderReviewServiceImpl.getReviewListByLawyerAndType?pageNum={}, pageSize={}, lawyerUserId={}, type={}, currentUserId={}",
|
|
|
+ pageNum, pageSize, lawyerUserId, type, currentUserId);
|
|
|
+
|
|
|
+ if (lawyerUserId == null) {
|
|
|
+ return R.fail("律师ID不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ Page<OrderReviewVo> page = new Page<>(pageNum, pageSize);
|
|
|
+ IPage<OrderReviewVo> result = orderReviewMapper.getReviewListByLawyerAndType(page, lawyerUserId, type, currentUserId);
|
|
|
+
|
|
|
+ // 处理评价图片JSON字符串转换为列表
|
|
|
+ if (result.getRecords() != null) {
|
|
|
+ for (OrderReviewVo vo : result.getRecords()) {
|
|
|
+ // 处理评价图片:从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<>());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return R.data(result);
|
|
|
+ }
|
|
|
}
|
|
|
|