CommentService.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <?php
  2. namespace App\Services\Client;
  3. use App\Models\CoachOrderComment;
  4. use App\Models\CoachStatistic;
  5. use App\Models\Order;
  6. use Illuminate\Support\Facades\Auth;
  7. use Illuminate\Support\Facades\DB;
  8. use Illuminate\Support\Facades\Log;
  9. class CommentService
  10. {
  11. /**
  12. * 提交评价
  13. */
  14. public function create(array $data): array
  15. {
  16. // 开启事务
  17. return DB::transaction(function () use ($data) {
  18. // 获取订单信息
  19. $order = Order::with('coach')->findOrFail($data['order_id']);
  20. // 记录订单信息
  21. Log::info('订单信息', [
  22. 'order_id' => $order->id,
  23. 'coach_id' => $order->coach_id,
  24. 'order_data' => $order->toArray()
  25. ]);
  26. // 检查订单是否属于当前用户
  27. if ($order->user_id !== Auth::id()) {
  28. abort(403, '无权评价此订单');
  29. }
  30. // 检查订单是否已评价
  31. if (CoachOrderComment::where('order_id', $order->id)->exists()) {
  32. abort(400, '订单已评价');
  33. }
  34. // 确保技师ID存在
  35. if (empty($order->coach_id)) {
  36. abort(400, '订单未关联技师');
  37. }
  38. // 创建评价
  39. $comment = CoachOrderComment::create([
  40. 'order_id' => $order->id,
  41. 'user_id' => Auth::id(),
  42. 'coach_id' => $order->coach_id,
  43. 'score' => $data['score'],
  44. 'content' => $data['content'] ?? null,
  45. 'images' => $data['images'] ?? null,
  46. 'is_anonymous' => $data['is_anonymous'] ?? false,
  47. 'status' => 1,
  48. ]);
  49. // 关联标签
  50. if (!empty($data['tag_ids'])) {
  51. $comment->tags()->attach($data['tag_ids']);
  52. }
  53. // 更新技师统计数据
  54. $this->updateCoachStatistics($order->coach_id);
  55. return [
  56. 'id' => $comment->id,
  57. 'message' => '评价提交成功',
  58. ];
  59. });
  60. }
  61. /**
  62. * 获取技师评价列表
  63. */
  64. public function getCoachComments(int $coachId, array $filters = []): array
  65. {
  66. $query = CoachOrderComment::query()
  67. ->where('coach_id', $coachId)
  68. ->where('status', 1)
  69. ->with(['user', 'tags'])
  70. ->latest();
  71. // 评分筛选
  72. if (isset($filters['score'])) {
  73. $query->where('score', $filters['score']);
  74. }
  75. // 标签筛选
  76. if (!empty($filters['tag_id'])) {
  77. $query->whereHas('tags', function ($q) use ($filters) {
  78. $q->where('tag_id', $filters['tag_id']);
  79. });
  80. }
  81. // 分页获取评价列表
  82. $comments = $query->paginate($filters['per_page'] ?? 10);
  83. return [
  84. 'total' => $comments->total(),
  85. 'current_page' => $comments->currentPage(),
  86. 'last_page' => $comments->lastPage(),
  87. 'items' => $comments->map(function ($comment) {
  88. return [
  89. 'id' => $comment->id,
  90. 'score' => $comment->score,
  91. 'content' => $comment->content,
  92. 'images' => $comment->images,
  93. 'created_at' => $comment->created_at->format('Y-m-d H:i:s'),
  94. 'user' => $comment->is_anonymous ? null : [
  95. 'id' => $comment->user->id,
  96. 'nickname' => $comment->user->nickname,
  97. 'avatar' => $comment->user->avatar,
  98. ],
  99. 'tags' => $comment->tags->map(function ($tag) {
  100. return [
  101. 'id' => $tag->id,
  102. 'name' => $tag->name,
  103. ];
  104. }),
  105. ];
  106. }),
  107. ];
  108. }
  109. /**
  110. * 更新技师统计数据
  111. */
  112. protected function updateCoachStatistics(int $coachId): void
  113. {
  114. // 获取技师所有评价
  115. $comments = CoachOrderComment::where('coach_id', $coachId)
  116. ->where('status', 1)
  117. ->get();
  118. // 计算评分统计
  119. $totalScore = $comments->sum('score');
  120. $commentCount = $comments->count();
  121. $avgScore = $commentCount > 0 ? round($totalScore / $commentCount, 2) : 0;
  122. $goodCount = $comments->where('score', '>=', 4)->count();
  123. $mediumCount = $comments->where('score', '=', 3)->count();
  124. $badCount = $comments->where('score', '<=', 2)->count();
  125. // 计算标签统计
  126. $tagCounts = [];
  127. $comments->load('tags');
  128. foreach ($comments as $comment) {
  129. foreach ($comment->tags as $tag) {
  130. $tagCounts[$tag->id] = ($tagCounts[$tag->id] ?? 0) + 1;
  131. }
  132. }
  133. // 更新或创建统计记录
  134. $statistic = CoachStatistic::firstOrNew(['coach_id' => $coachId]);
  135. $statistic->updateScoreStatistics(
  136. $avgScore,
  137. $commentCount,
  138. $goodCount,
  139. $mediumCount,
  140. $badCount
  141. );
  142. $statistic->updateTagStatistics($tagCounts);
  143. }
  144. }