소스 검색

fixed:用户端->订单-计算订单金额

刘学玺 4 달 전
부모
커밋
5be1b71afe
1개의 변경된 파일58개의 추가작업 그리고 197개의 파일을 삭제
  1. 58 197
      app/Services/Client/OrderService.php

+ 58 - 197
app/Services/Client/OrderService.php

@@ -14,7 +14,6 @@ use App\Enums\TechnicianStatus;
 use App\Enums\TransactionType;
 use App\Enums\UserStatus;
 use App\Models\AgentInfo;
-use App\Models\CoachSchedule;
 use App\Models\CoachUser;
 use App\Models\MemberAddress;
 use App\Models\MemberUser;
@@ -29,6 +28,7 @@ use App\Services\Client\Traits\HandlesPayments;
 use App\Services\Client\Traits\ValidatesServiceTime;
 use Carbon\Carbon;
 use Exception;
+use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Log;
@@ -255,8 +255,21 @@ readonly class OrderService
                 );
 
                 // 加钟订单使用原订单地址和技师ID
-                if ($data['order_id']) {
-                    $order = Order::find($data['order_id']);
+                if (!empty($data['order_id'])) {
+                    $order = Order::findOrFail($data['order_id']);
+
+                    // 验证订单状态
+                    abort_if(
+                        !in_array($order->state, [
+                            OrderStatus::PAID->value,
+                            OrderStatus::ACCEPTED->value,
+                            OrderStatus::SERVICE->value,
+                            OrderStatus::SERVICE_ING->value,
+                        ]),
+                        422,
+                        '原订单状态不允许加钟'
+                    );
+
                     $data['address_id'] = $order->address_id;
                     $data['coach_id'] = $order->coach_id;
                     $data['service_time'] = $order->service_end_time;
@@ -326,33 +339,10 @@ readonly class OrderService
             ->where('state', ProjectStatus::OPEN->value)
             ->firstOrFail();
 
-        // 验证服务时间
-        if (! empty($data['service_time'])) {
-            $serviceTime = Carbon::parse($data['service_time']);
-            abort_if(
-                $serviceTime->isPast(),
-                400,
-                '服务时间不能早于当前时间'
-            );
-
-            // 如果指定了技师,验证服务时间是否可用
-            if (! empty($data['coach_id'])) {
-                $this->validateServiceTime($data['coach_id'], $data['service_time']);
-            }
-        }
-
-        // 验证技师状态(如果有)
-        if (! empty($data['coach_id'])) {
-            $this->validateCoach($data['coach_id']);
+        // 验证服务时间和技师状态
+        if (! empty($data['service_time']) && ! empty($data['coach_id'])) {
+            $this->validateServiceTimeParams($data['coach_id'], $data['service_time']);
         }
-
-        // TODO: 验证代理商状态(如果有)
-        // 验证代理商状态(如果有)
-        // if (! empty($data['agent_id'])) {
-        //     $agent = AgentInfo::where('id', $data['agent_id'])
-        //         ->where('state', AgentStatus::OPEN->value)
-        //         ->firstOrFail();
-        // }
     }
 
     /**
@@ -460,7 +450,7 @@ readonly class OrderService
      */
     private function notifyOrderCreated(Order $order): void
     {
-        // TODO: 实现订单创建通知逻辑
+        // TODO: 实现订单创建通������
         // 1. 通知用户
         // event(new OrderCreatedEvent($order));
 
@@ -510,32 +500,20 @@ readonly class OrderService
             && $orderType !== OrderType::GRAB;
     }
 
-    // 提取方法:验证技师
-    public function validateCoach(int $coachId): CoachUser
+    /**
+     * 验证技师状态
+     */
+    private function validateCoach(int $coachId): CoachUser
     {
-        // 查询技师基本信息
         $coach = CoachUser::query()
-            ->with(['info', 'qual', 'real'])
+            ->with(['info'])
             ->where('id', $coachId)
+            ->where('state', TechnicianStatus::ACTIVE->value)
             ->first();
 
-        // 验证技师是否存在
-        abort_if(! $coach, 400, '技师不存在');
-
-        // 验证技师状态
-        abort_if($coach->state !== TechnicianStatus::ACTIVE->value, 400, '技师未激活');
-
-        // 验证基本信息认证
+        abort_if(! $coach, 400, '技师不存在或未激活');
         abort_if(! $coach->info || $coach->info->state !== TechnicianAuthStatus::PASSED->value,
-            400, '技师基本信息未认证');
-
-        // 验证资质认证
-        abort_if(! $coach->qual || $coach->qual->state !== TechnicianAuthStatus::PASSED->value,
-            400, '技师资质未认证');
-
-        // 验证实名认证
-        abort_if(! $coach->real || $coach->real->state !== TechnicianAuthStatus::PASSED->value,
-            400, '技师实名未认证');
+            400, '技师未通过认证');
 
         return $coach;
     }
@@ -784,7 +762,7 @@ readonly class OrderService
                 // 1. 验证用户和订单
                 $order = $this->validateOrderForFinish($userId, $orderId);
 
-                // 2. 验证技师状
+                // 2. 验证技师状���
                 $coach = $this->validateCoach($order->coach_id);
 
                 // 4. 完成订单
@@ -991,7 +969,7 @@ readonly class OrderService
     }
 
     /**
-     * 格式化订单列表项
+     * �������化订��列表项
      */
     private function formatOrderListItem(Order $order): array
     {
@@ -1278,7 +1256,7 @@ readonly class OrderService
                 break;
         }
 
-        // 计算实际可退金额(总金额减去违约金)
+        // 计算实际可��金额(总金额减去违约金)
         $totalRefund = bcsub($order->total_amount, $deductAmount, 2);
 
         // 优先退还用户使用的余额部分
@@ -1598,7 +1576,7 @@ readonly class OrderService
      * @param  float  $distance  距离(公里)
      * @param array{
      *     min_distance: float,  // 最小计费距离(公里)
-     *     min_fee: float,      // 小路费(元)
+     *     min_fee: float,      // ���小路费(元)
      *     per_km_fee: float,   // 每公里费用(元)
      *     max_distance: float,  // 最大服务距离(公里)
      *     max_fee: float,      // 最大路费(元)
@@ -1782,7 +1760,7 @@ readonly class OrderService
             ->where('state', ProjectStatus::OPEN->value)
             ->first();
 
-        abort_if(! $project, 404, '项目不存在或状态异常');
+        abort_if(! $project, 404, '项目不���在或���态异常');
 
         // 如果有代理商,获取代理商价格
         if ($agentId) {
@@ -1800,7 +1778,7 @@ readonly class OrderService
      */
     private function getAgentProjectPrice(int $agentId, int $projectId): ?object
     {
-        return DB::table('agent_projects')
+        return DB::table('agent_project')
             ->where('agent_id', $agentId)
             ->where('project_id', $projectId)
             ->where('state', 'enable')
@@ -1898,7 +1876,7 @@ readonly class OrderService
             }
 
             // 如果有有效距离,返回最小值;否则返回0
-            return !empty($distances) ? min($distances) : 0.0;
+            return ! empty($distances) ? min($distances) : 0.0;
 
         } catch (\Exception $e) {
             Log::error('计算距离失败', [
@@ -1908,6 +1886,7 @@ readonly class OrderService
                 'lat' => $lat,
                 'lng' => $lng,
             ]);
+
             return 0.0;
         }
     }
@@ -1974,7 +1953,7 @@ readonly class OrderService
     {
 
         try {
-            // 查询单信息
+            // 查询��单信息
             $order = Order::where('id', $orderId)
                 ->whereIn('state', [OrderStatus::CREATED->value])
                 ->firstOrFail();
@@ -2354,81 +2333,6 @@ readonly class OrderService
         }
     }
 
-    /**
-     * 验证服务时间参数
-     */
-    private function validateServiceTimeParams(int $coachId, string $serviceTime): void
-    {
-        // 验证技师状态是否正常
-        $coach = CoachUser::where('id', $coachId)
-            ->where('state', TechnicianStatus::ACTIVE->value)
-            ->where('auth_state', TechnicianAuthStatus::PASSED->value)
-            ->firstOrFail();
-
-        // 验证时间格式并检查是否早于当前时间
-        $serviceDateTime = Carbon::parse($serviceTime);
-        abort_if(
-            $serviceDateTime->isPast(),
-            400,
-            '服务时间不能早于当前时间'
-        );
-
-        // 验证预约提前时间(至少提前指定小时)
-        $minAdvanceHours = config('business.min_advance_hours', 2);
-        abort_if(
-            $serviceDateTime->diffInHours(now()) < $minAdvanceHours,
-            400,
-            "需要至少提前{$minAdvanceHours}小时预约"
-        );
-
-        // 验证预约时间范围(最多提前指定天数)
-        $maxAdvanceDays = config('business.max_advance_days', 7);
-        abort_if(
-            $serviceDateTime->diffInDays(now()) > $maxAdvanceDays,
-            400,
-            "最多只能提前{$maxAdvanceDays}天预约"
-        );
-    }
-
-    /**
-     * 验证是否在工作时间内
-     */
-    private function validateWorkingHours(string $serviceTime, array $workSchedule): void
-    {
-        $serviceDateTime = Carbon::parse($serviceTime);
-
-        // 检查是否为工作日
-        $dayOfWeek = $serviceDateTime->dayOfWeek;
-        abort_if(
-            ! in_array($dayOfWeek, $workSchedule['work_days']),
-            400,
-            '该时间不在技师工作日内'
-        );
-
-        // 检查是否为特殊休息日
-        $dateStr = $serviceDateTime->format('Y-m-d');
-        abort_if(
-            in_array($dateStr, $workSchedule['rest_dates']),
-            400,
-            '技师该日期休息'
-        );
-
-        // 检查是否在工作时间范围内
-        $timeStr = $serviceDateTime->format('H:i');
-        $startTime = Carbon::parse($workSchedule['work_hours']['start']);
-        $endTime = Carbon::parse($workSchedule['work_hours']['end']);
-
-        abort_if(
-            $timeStr < $startTime->format('H:i') || $timeStr > $endTime->format('H:i'),
-            400,
-            sprintf(
-                '服务时间需在%s-%s之间',
-                $startTime->format('H:i'),
-                $endTime->format('H:i')
-            )
-        );
-    }
-
     /**
      * 检查订单时间冲突
      */
@@ -2551,43 +2455,6 @@ readonly class OrderService
         return $order;
     }
 
-    /**
-     * 创建评价记录
-     */
-    // private function createEvaluation(Order $order, array $data): OrderEvaluation
-    // {
-    //     // 创建评价记录
-    //     $evaluation = $order->evaluation()->create([
-    //         'user_id' => $order->user_id,
-    //         'coach_id' => $order->coach_id,
-    //         'project_id' => $order->project_id,
-    //         'score' => $data['score'],
-    //         'content' => $data['content'],
-    //         'images' => $data['images'] ?? [],
-    //         'state' => 'normal',
-    //     ]);
-
-    //     // 创建评价标签
-    //     if (! empty($data['tags'])) {
-    //         // TODO: 创建评价标签
-    //         $this->createEvaluationTags($evaluation, $data['tags']);
-    //     }
-
-    //     return $evaluation;
-    // }
-
-    /**
-     * 创建评价标签
-     */
-    // private function createEvaluationTags(OrderEvaluation $evaluation, array $tags): void
-    // {
-    //     $tagIds = EvaluationTag::whereIn('id', $tags)
-    //         ->where('state', 'enable')
-    //         ->pluck('id');
-
-    //     $evaluation->tags()->attach($tagIds);
-    // }
-
     /**
      * 更新技师评分
      */
@@ -2667,36 +2534,30 @@ readonly class OrderService
     //     // Cache::tags(['coach_evaluations'])->forget("coach:{$order->coach_id}");
     // }
 
-    /**
-     * 获取技师工作时间安排
-     */
-    private function getCoachWorkSchedule(int $coachId): array
+    private function getNearbyCoaches(float $lat, float $lng, float $radius = 5.0): Collection
+    {
+        // 获取在线技师列表
+        return CoachUser::query()
+            ->with(['info'])
+            ->where('state', TechnicianStatus::ACTIVE->value)
+            ->whereHas('info', fn ($q) => $q->where('state', TechnicianAuthStatus::PASSED->value))
+            ->get();
+    }
+
+    private function validateCoachForGrab(int $coachId): CoachUser
     {
-        // 查询技师排班信息
-        $schedule = CoachSchedule::where('coach_id', $coachId)
-            ->where('state', 1)
+        $coach = CoachUser::query()
+            ->with(['info'])
+            ->where('id', $coachId)
+            ->where('state', TechnicianStatus::ACTIVE->value)
             ->first();
 
-        // 如果没有排班信息,返回默认工作时间
-        if (! $schedule) {
-            return [
-                'work_days' => range(1, 7),          // 默认每天工作
-                'work_hours' => [
-                    'start' => '09:00',              // 默认早9点开始
-                    'end' => '21:00',                // 默认晚9点结束
-                ],
-                'rest_dates' => [],                  // 默认无休息日
-            ];
-        }
+        abort_if(! $coach, 400, '技师不存在或未激活');
 
-        // 返回技师的实际排班信息
-        return [
-            'work_days' => json_decode($schedule->work_days, true),
-            'work_hours' => [
-                'start' => $schedule->work_start_time,
-                'end' => $schedule->work_end_time,
-            ],
-            'rest_dates' => json_decode($schedule->rest_dates, true) ?? [],
-        ];
+        // 验证技师认证状态
+        abort_if(! $coach->info || $coach->info->state !== TechnicianAuthStatus::PASSED->value,
+            400, '技师未通过认证');
+
+        return $coach;
     }
 }