|
@@ -0,0 +1,164 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Services\Client;
|
|
|
+
|
|
|
+use App\Models\CoachOrderComment;
|
|
|
+use App\Models\CoachStatistic;
|
|
|
+use App\Models\Order;
|
|
|
+use Illuminate\Support\Facades\Auth;
|
|
|
+use Illuminate\Support\Facades\DB;
|
|
|
+use Illuminate\Support\Facades\Log;
|
|
|
+
|
|
|
+class CommentService
|
|
|
+{
|
|
|
+ /**
|
|
|
+ * 提交评价
|
|
|
+ */
|
|
|
+ public function create(array $data): array
|
|
|
+ {
|
|
|
+ // 开启事务
|
|
|
+ return DB::transaction(function () use ($data) {
|
|
|
+ // 获取订单信息
|
|
|
+ $order = Order::with('coach')->findOrFail($data['order_id']);
|
|
|
+
|
|
|
+ // 记录订单信息
|
|
|
+ Log::info('订单信息', [
|
|
|
+ 'order_id' => $order->id,
|
|
|
+ 'coach_id' => $order->coach_id,
|
|
|
+ 'order_data' => $order->toArray()
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 检查订单是否属于当前用户
|
|
|
+ if ($order->user_id !== Auth::id()) {
|
|
|
+ abort(403, '无权评价此订单');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查订单是否已评价
|
|
|
+ if (CoachOrderComment::where('order_id', $order->id)->exists()) {
|
|
|
+ abort(400, '订单已评价');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保技师ID存在
|
|
|
+ if (empty($order->coach_id)) {
|
|
|
+ abort(400, '订单未关联技师');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建评价
|
|
|
+ $comment = CoachOrderComment::create([
|
|
|
+ 'order_id' => $order->id,
|
|
|
+ 'user_id' => Auth::id(),
|
|
|
+ 'coach_id' => $order->coach_id,
|
|
|
+ 'score' => $data['score'],
|
|
|
+ 'content' => $data['content'] ?? null,
|
|
|
+ 'images' => $data['images'] ?? null,
|
|
|
+ 'is_anonymous' => $data['is_anonymous'] ?? false,
|
|
|
+ 'status' => 1,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 关联标签
|
|
|
+ if (!empty($data['tag_ids'])) {
|
|
|
+ $comment->tags()->attach($data['tag_ids']);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新技师统计数据
|
|
|
+ $this->updateCoachStatistics($order->coach_id);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'id' => $comment->id,
|
|
|
+ 'message' => '评价提交成功',
|
|
|
+ ];
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取技师评价列表
|
|
|
+ */
|
|
|
+ public function getCoachComments(int $coachId, array $filters = []): array
|
|
|
+ {
|
|
|
+ $query = CoachOrderComment::query()
|
|
|
+ ->where('coach_id', $coachId)
|
|
|
+ ->where('status', 1)
|
|
|
+ ->with(['user', 'tags'])
|
|
|
+ ->latest();
|
|
|
+
|
|
|
+ // 评分筛选
|
|
|
+ if (isset($filters['score'])) {
|
|
|
+ $query->where('score', $filters['score']);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 标签筛选
|
|
|
+ if (!empty($filters['tag_id'])) {
|
|
|
+ $query->whereHas('tags', function ($q) use ($filters) {
|
|
|
+ $q->where('tag_id', $filters['tag_id']);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分页获取评价列表
|
|
|
+ $comments = $query->paginate($filters['per_page'] ?? 10);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'total' => $comments->total(),
|
|
|
+ 'current_page' => $comments->currentPage(),
|
|
|
+ 'last_page' => $comments->lastPage(),
|
|
|
+ 'items' => $comments->map(function ($comment) {
|
|
|
+ return [
|
|
|
+ 'id' => $comment->id,
|
|
|
+ 'score' => $comment->score,
|
|
|
+ 'content' => $comment->content,
|
|
|
+ 'images' => $comment->images,
|
|
|
+ 'created_at' => $comment->created_at->format('Y-m-d H:i:s'),
|
|
|
+ 'user' => $comment->is_anonymous ? null : [
|
|
|
+ 'id' => $comment->user->id,
|
|
|
+ 'nickname' => $comment->user->nickname,
|
|
|
+ 'avatar' => $comment->user->avatar,
|
|
|
+ ],
|
|
|
+ 'tags' => $comment->tags->map(function ($tag) {
|
|
|
+ return [
|
|
|
+ 'id' => $tag->id,
|
|
|
+ 'name' => $tag->name,
|
|
|
+ ];
|
|
|
+ }),
|
|
|
+ ];
|
|
|
+ }),
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新技师统计数据
|
|
|
+ */
|
|
|
+ protected function updateCoachStatistics(int $coachId): void
|
|
|
+ {
|
|
|
+ // 获取技师所有评价
|
|
|
+ $comments = CoachOrderComment::where('coach_id', $coachId)
|
|
|
+ ->where('status', 1)
|
|
|
+ ->get();
|
|
|
+
|
|
|
+ // 计算评分统计
|
|
|
+ $totalScore = $comments->sum('score');
|
|
|
+ $commentCount = $comments->count();
|
|
|
+ $avgScore = $commentCount > 0 ? round($totalScore / $commentCount, 2) : 0;
|
|
|
+ $goodCount = $comments->where('score', '>=', 4)->count();
|
|
|
+ $mediumCount = $comments->where('score', '=', 3)->count();
|
|
|
+ $badCount = $comments->where('score', '<=', 2)->count();
|
|
|
+
|
|
|
+ // 计算标签统计
|
|
|
+ $tagCounts = [];
|
|
|
+ $comments->load('tags');
|
|
|
+ foreach ($comments as $comment) {
|
|
|
+ foreach ($comment->tags as $tag) {
|
|
|
+ $tagCounts[$tag->id] = ($tagCounts[$tag->id] ?? 0) + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新或创建统计记录
|
|
|
+ $statistic = CoachStatistic::firstOrNew(['coach_id' => $coachId]);
|
|
|
+ $statistic->updateScoreStatistics(
|
|
|
+ $avgScore,
|
|
|
+ $commentCount,
|
|
|
+ $goodCount,
|
|
|
+ $mediumCount,
|
|
|
+ $badCount
|
|
|
+ );
|
|
|
+ $statistic->updateTagStatistics($tagCounts);
|
|
|
+ }
|
|
|
+}
|