|
@@ -4,6 +4,7 @@ namespace App\Services\Coach;
|
|
|
|
|
|
use App\Enums\OrderGrabRecordStatus;
|
|
|
use App\Enums\OrderStatus;
|
|
|
+use App\Enums\OrderType;
|
|
|
use App\Enums\ProjectStatus;
|
|
|
use App\Enums\TechnicianAuthStatus;
|
|
|
use App\Enums\TechnicianLocationType;
|
|
@@ -345,6 +346,9 @@ class OrderService
|
|
|
// 验证订单状态
|
|
|
abort_if($order->state !== OrderStatus::CREATED->value, 400, '订单状态异常,无法抢单');
|
|
|
|
|
|
+ // 验证订单类型
|
|
|
+ abort_if($order->type !== OrderType::GRAB->value, 400, '该订单不是抢单类型');
|
|
|
+
|
|
|
// 检查技师是否已参与抢单
|
|
|
$existingGrab = $coach->grabRecords()
|
|
|
->where('order_id', $orderId)
|
|
@@ -402,17 +406,65 @@ class OrderService
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 计算两点之间的距离(公里)
|
|
|
+ * 技师接单
|
|
|
+ *
|
|
|
+ * @param int $userId 技师用户ID
|
|
|
+ * @param int $orderId 订单ID
|
|
|
*/
|
|
|
- private function calculateDistance($lat1, $lon1, $lat2, $lon2): float
|
|
|
+ public function acceptOrder(int $userId, int $orderId): array
|
|
|
{
|
|
|
- $theta = $lon1 - $lon2;
|
|
|
- $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1))
|
|
|
- * cos(deg2rad($lat2)) * cos(deg2rad($theta));
|
|
|
- $dist = acos($dist);
|
|
|
- $dist = rad2deg($dist);
|
|
|
- $miles = $dist * 60 * 1.1515;
|
|
|
-
|
|
|
- return round($miles * 1.609344, 1); // 转换为公里并保留一位小数
|
|
|
+ return DB::transaction(function () use ($userId, $orderId) {
|
|
|
+ try {
|
|
|
+ // 加载用户和技师信息
|
|
|
+ $user = MemberUser::with([
|
|
|
+ 'coach',
|
|
|
+ 'coach.info',
|
|
|
+ 'coach.real',
|
|
|
+ 'coach.qual',
|
|
|
+ ])->findOrFail($userId);
|
|
|
+
|
|
|
+ // 验证技师信息
|
|
|
+ [$coach, $location] = $this->validateCoach($user);
|
|
|
+
|
|
|
+ // 获取订单信息并加锁
|
|
|
+ $order = Order::lockForUpdate()->findOrFail($orderId);
|
|
|
+
|
|
|
+ // 验证订单状态
|
|
|
+ abort_if($order->state !== OrderStatus::ASSIGNED->value, 400, '订单状态异常,无法接单');
|
|
|
+
|
|
|
+ // 验证订单是否分配给该技师
|
|
|
+ abort_if($order->coach_id !== $coach->id, 403, '该订单未分配给您');
|
|
|
+
|
|
|
+ // 更新订单状态
|
|
|
+ $order->update([
|
|
|
+ 'state' => OrderStatus::ACCEPTED->value,
|
|
|
+ 'accepted_at' => now(),
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 记录日志
|
|
|
+ Log::info('技师接单成功', [
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'coach_id' => $coach->id,
|
|
|
+ 'order_id' => $orderId,
|
|
|
+ 'order_no' => $order->order_no,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'message' => '接单成功',
|
|
|
+ 'order_id' => $orderId,
|
|
|
+ 'order_no' => $order->order_no,
|
|
|
+ ];
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error('技师接单失败', [
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'order_id' => $orderId,
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
+ 'file' => $e->getFile(),
|
|
|
+ 'line' => $e->getLine(),
|
|
|
+ ]);
|
|
|
+ throw $e;
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
}
|