Browse Source

feat: 更新教练统计模型和订单服务逻辑以支持评分和订单统计
- 修改CoachStatistic模型,添加评分相关字段和订单统计字段
- 在OrderService中实现更新教练评分的逻辑,使用CoachStatistic模型更新或创建统计记录
- 优化评分计算逻辑,确保统计信息的准确性

刘学玺 3 months ago
parent
commit
5a0dfbcba0
2 changed files with 81 additions and 72 deletions
  1. 53 40
      app/Models/CoachStatistic.php
  2. 28 32
      app/Services/Client/OrderService.php

+ 53 - 40
app/Models/CoachStatistic.php

@@ -2,68 +2,81 @@
 
 namespace App\Models;
 
-use Illuminate\Database\Eloquent\Factories\HasFactory;
+use App\Enums\OrderStatus;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Support\Facades\DB;
 
 class CoachStatistic extends Model
 {
-    use HasFactory;
-
-    protected $table = 'coach_statistics';
-
     protected $fillable = [
         'coach_id',
-        'avg_score',
+        // 评分相关
+        'score',
+        'service_score',
+        'appearance_score',
+        'attitude_score',
+        'professional_score',
+
+        // 评价统计
         'comment_count',
         'good_comment_count',
         'medium_comment_count',
         'bad_comment_count',
-        'tag_statistics',
+
+        // 订单统计
+        'order_count',
+        'completed_order_count',
+        'cancel_order_count',
+        'reject_order_count',
+
+        // 月度统计
+        'month_order_count',
+        'month_completed_count',
+        'month_income',
+
+        // 其他统计
+        'total_income',
+        'completion_rate',
+        'avg_response_time'
     ];
 
     protected $casts = [
-        'avg_score' => 'decimal:2',
+        // 评分相关
+        'score' => 'float',
+        'service_score' => 'float',
+        'appearance_score' => 'float',
+        'attitude_score' => 'float',
+        'professional_score' => 'float',
+
+        // 评价统计
         'comment_count' => 'integer',
         'good_comment_count' => 'integer',
         'medium_comment_count' => 'integer',
         'bad_comment_count' => 'integer',
-        'tag_statistics' => 'array',
+
+        // 订单统计
+        'order_count' => 'integer',
+        'completed_order_count' => 'integer',
+        'cancel_order_count' => 'integer',
+        'reject_order_count' => 'integer',
+
+        // 月度统计
+        'month_order_count' => 'integer',
+        'month_completed_count' => 'integer',
+        'month_income' => 'float',
+
+        // 其他统计
+        'total_income' => 'float',
+        'completion_rate' => 'float',
+        'avg_response_time' => 'integer'
     ];
 
     /**
-     * 获取统计所属的技师
+     * 关联技师
      */
-    public function coach()
+    public function coach(): BelongsTo
     {
         return $this->belongsTo(CoachUser::class, 'coach_id');
     }
-
-    /**
-     * 更新标签统计
-     */
-    public function updateTagStatistics(array $tagCounts): bool
-    {
-        return $this->update([
-            'tag_statistics' => $tagCounts,
-        ]);
-    }
-
-    /**
-     * 更新评分统计
-     */
-    public function updateScoreStatistics(
-        float $avgScore,
-        int $commentCount,
-        int $goodCount,
-        int $mediumCount,
-        int $badCount
-    ): bool {
-        return $this->update([
-            'avg_score' => $avgScore,
-            'comment_count' => $commentCount,
-            'good_comment_count' => $goodCount,
-            'medium_comment_count' => $mediumCount,
-            'bad_comment_count' => $badCount,
-        ]);
-    }
 }

+ 28 - 32
app/Services/Client/OrderService.php

@@ -36,6 +36,7 @@ use App\Services\Client\Traits\HandlesPayments;
 use App\Services\Client\Traits\HandlesOrderRecords;
 use App\Services\Client\Traits\ValidatesServiceTime;
 use App\Services\Client\Traits\CalculatesOrderAmounts;
+use App\Models\CoachStatistic;
 
 readonly class OrderService
 {
@@ -2568,7 +2569,7 @@ readonly class OrderService
 
                 // 3. 更新技师评分
                 // TODO: 更新技师评分
-                // $this->updateCoachScore($order->coach_id);
+                $this->updateCoachScore($order->coach_id);
 
                 // 4. 更新订单状态
                 $this->updateOrderEvaluationStatus($order);
@@ -2621,27 +2622,6 @@ readonly class OrderService
         return $order;
     }
 
-    /**
-     * 更新技师评分
-     */
-    // private function updateCoachScore(int $coachId): void
-    // {
-    //     $coach = CoachUser::findOrFail($coachId);
-
-    //     // 计算平均分
-    //     $avgScore = OrderEvaluation::where('coach_id', $coachId)
-    //         ->where('state', 'normal')
-    //         ->avg('score');
-
-    //     // 更新技师评分
-    //     $coach->info()->update([
-    //         'score' => round($avgScore, 1),
-    //         'evaluation_count' => OrderEvaluation::where('coach_id', $coachId)
-    //             ->where('state', 'normal')
-    //             ->count(),
-    //     ]);
-    // }
-
     /**
      * 更新订单评价状态
      */
@@ -2814,7 +2794,7 @@ readonly class OrderService
             $order->update(['state' => OrderStatus::COMPLETED->value]);
 
             // 更新技师评分
-            // $this->updateCoachScore($order->coach_id);
+            $this->updateCoachScore($order->coach_id);
 
             // 记录订单状态变更
             OrderRecord::create([
@@ -2852,7 +2832,17 @@ readonly class OrderService
                 DB::raw('AVG(service_score) as avg_service_score'),
                 DB::raw('AVG(appearance_score) as avg_appearance_score'),
                 DB::raw('AVG(attitude_score) as avg_attitude_score'),
-                DB::raw('AVG(professional_score) as avg_professional_score')
+                DB::raw('AVG(professional_score) as avg_professional_score'),
+                DB::raw('COUNT(*) as total_comments')
+            ])
+            ->first();
+
+        // 获取订单统计
+        $orderCounts = DB::table('order')
+            ->where('coach_id', $coachId)
+            ->select([
+                DB::raw('COUNT(*) as total_orders'),
+                DB::raw('COUNT(CASE WHEN state = ' . OrderStatus::COMPLETED->value . ' THEN 1 END) as completed_orders')
             ])
             ->first();
 
@@ -2863,14 +2853,20 @@ readonly class OrderService
                 $avgScores->avg_attitude_score +
                 $avgScores->avg_professional_score) / 4, 1);
 
-            // 更新技师评分
-            $coach->update([
-                'score' => $overallScore,
-                'service_score' => round($avgScores->avg_service_score, 1),
-                'appearance_score' => round($avgScores->avg_appearance_score, 1),
-                'attitude_score' => round($avgScores->avg_attitude_score, 1),
-                'professional_score' => round($avgScores->avg_professional_score, 1)
-            ]);
+            // 更新或创建统计记录
+            CoachStatistic::updateOrCreate(
+                ['coach_id' => $coachId],
+                [
+                    'score' => $overallScore,
+                    'service_score' => round($avgScores->avg_service_score, 1),
+                    'appearance_score' => round($avgScores->avg_appearance_score, 1),
+                    'attitude_score' => round($avgScores->avg_attitude_score, 1),
+                    'professional_score' => round($avgScores->avg_professional_score, 1),
+                    'comment_count' => $avgScores->total_comments,
+                    'order_count' => $orderCounts->total_orders,
+                    'completed_order_count' => $orderCounts->completed_orders
+                ]
+            );
         }
     }
 }