<?php namespace App\Http\Controllers\Client; use App\Http\Controllers\Controller; use App\Services\Client\OrderService; use Illuminate\Http\Request; class OrderController extends Controller { protected OrderService $service; public function __construct(OrderService $service) { $this->service = $service; } /** * 订单初始化 */ public function initialize(Request $request) { $userId = Auth::id(); $coachId = $request->input('coach_id'); $areaCode = $request->input('area_code'); $projectId = $request->input('project_id'); return $this->service->initialize($userId, $coachId, $areaCode, $projectId); } /** * 结束订单 */ public function finish(Request $request) { $userId = Auth::id(); $orderId = $request->input('order_id'); return $this->service->finishOrder($userId, $orderId); } /** * 确认技师离开 */ public function confirmLeave(Request $request) { $userId = Auth::id(); $orderId = $request->input('order_id'); return $this->service->confirmLeave($userId, $orderId); } /** * 取消订单 */ public function cancel(Request $request) { $userId = Auth::id(); $orderId = $request->input('order_id'); return $this->service->cancelOrder($userId, $orderId); } /** * 获取订单列表 */ public function list() { return $this->service->getOrderList(); } /** * 获取订单详情 */ public function detail($id) { return $this->service->getOrderDetail($id); } /** * 订单退款 */ public function refund($id) { return $this->service->refundOrder($id); } /** * 获取代理商配置 */ public function getAgentConfig(Request $request) { $agentId = $request->input('agent_id'); return $this->service->getAgentConfig($agentId); } /** * 获取技师配置 */ public function getCoachConfig(Request $request) { $coachId = $request->input('coach_id'); return $this->service->getCoachConfig($coachId); } /** * 计算路费金额 */ public function calculateDeliveryFee(Request $request) { $coachId = $request->input('coach_id'); $agentId = $request->input('agent_id'); $distance = $request->input('distance'); $latitude = $request->input('latitude'); $longitude = $request->input('longitude'); if ($agentId) { return $this->service->calculateDeliveryFee($coachId, $agentId, $distance); } else { return $this->service->calculateDeliveryFeeByLocation($coachId, $latitude, $longitude, $distance); } } /** * 计算订单金额 */ public function calculateOrderAmount(Request $request) { $userId = Auth::id(); $addressId = $request->input('address_id'); $coachId = $request->input('coach_id'); $projectId = $request->input('project_id'); $agentId = $request->input('agent_id'); $useBalance = $request->input('use_balance', 0); return $this->service->calculateOrderAmount($userId, $addressId, $coachId, $projectId, $agentId, $useBalance); } /** * 创建订单 */ public function create(Request $request) { $userId = Auth::id(); $projectId = $request->input('project_id'); $addressId = $request->input('address_id'); $coachId = $request->input('coach_id'); $useBalance = $request->input('use_balance', 0); $orderId = $request->input('order_id'); return $this->service->createOrder($userId, $projectId, $addressId, $coachId, $useBalance, $orderId); } /** * 加钟 */ public function addTime(Request $request, $orderId) { $userId = Auth::id(); return $this->service->addTime($userId, $orderId); } /** * 指定技师 */ public function assignCoach(Request $request, $orderId) { $userId = Auth::id(); $coachId = $request->input('coach_id'); return $this->service->assignCoach($userId, $orderId, $coachId); } /** * 获取代理商配置 */ public function getAgentConfig($agentId) { $agent = AgentInfo::where('id', $agentId) ->where('state', 'enable') ->firstOrFail(); $config = AgentConfig::where('agent_id', $agentId)->firstOrFail(); return [ 'min_distance' => $config->min_distance, 'min_fee' => $config->min_fee, 'per_km_fee' => $config->per_km_fee ]; } /** * 获取技师配置 */ public function getCoachConfig($coachId) { $coach = CoachUser::where('id', $coachId) ->where('state', 'enable') ->where('auth_state', 'passed') ->firstOrFail(); $config = CoachConfig::where('coach_id', $coachId)->firstOrFail(); return [ 'delivery_fee_type' => $config->delivery_fee_type, 'charge_delivery_fee' => $config->charge_delivery_fee ]; } /** * 计算路费金额 */ public function calculateDeliveryFee($coachId, $agentId, $distance) { $coach = CoachUser::where('id', $coachId) ->where('state', 'enable') ->where('auth_state', 'passed') ->firstOrFail(); $coachConfig = CoachConfig::where('coach_id', $coachId)->firstOrFail(); if (!$coachConfig->charge_delivery_fee) { return 0; } $agentConfig = AgentConfig::where('agent_id', $agentId)->firstOrFail(); $fee = 0; if ($distance <= $agentConfig->min_distance) { $fee = $agentConfig->min_fee; } else { $extraDistance = $distance - $agentConfig->min_distance; $fee = $agentConfig->min_fee + ($extraDistance * $agentConfig->per_km_fee); } return $coachConfig->delivery_fee_type == 'round_trip' ? $fee * 2 : $fee; } /** * 计算订单金额 */ public function calculateOrderAmount($userId, $addressId, $coachId, $projectId, $agentId, $useBalance) { // 参数校验 $user = User::where('id', $userId) ->where('status', 1) ->firstOrFail(); $address = UserAddress::where('id', $addressId) ->where('user_id', $userId) ->firstOrFail(); $coach = CoachUser::where('id', $coachId) ->where('state', 'enable') ->where('auth_state', 'passed') ->firstOrFail(); $project = Project::where('id', $projectId) ->where('state', 'enable') ->firstOrFail(); // 计算金额 $projectAmount = $project->price; $deliveryFee = $this->calculateDeliveryFee($coachId, $agentId, $address->distance); $tipAmount = request()->has('order_id') ? Order::find(request()->input('order_id'))->tip_amount : 0; $couponAmount = 0; if (request()->has('coupon_id')) { $coupon = Coupon::where('id', request()->input('coupon_id')) ->where('state', 'enable') ->firstOrFail(); $couponAmount = $coupon->amount; } $totalAmount = $projectAmount + $deliveryFee + $tipAmount - $couponAmount; $balanceAmount = 0; $payAmount = $totalAmount; if ($useBalance) { $wallet = UserWallet::where('user_id', $userId)->first(); if ($wallet && $wallet->balance >= $totalAmount) { $balanceAmount = $totalAmount; $payAmount = 0; } else if ($wallet) { $balanceAmount = $wallet->balance; $payAmount = $totalAmount - $balanceAmount; } } return [ 'total_amount' => $totalAmount, 'balance_amount' => $balanceAmount, 'pay_amount' => $payAmount, 'coupon_amount' => $couponAmount, 'tip_amount' => $tipAmount, 'project_amount' => $projectAmount, 'delivery_fee' => $deliveryFee ]; } /** * 创建订单 */ public function createOrder($userId, $projectId, $addressId, $coachId, $useBalance, $orderId = null) { return DB::transaction(function() use ($userId, $projectId, $addressId, $coachId, $useBalance, $orderId) { // 参数校验 $user = User::where('id', $userId) ->where('status', 1) ->firstOrFail(); $address = UserAddress::where('id', $addressId) ->where('user_id', $userId) ->firstOrFail(); if (!$orderId) { $coach = CoachUser::where('id', $coachId) ->where('state', 'enable') ->where('auth_state', 'passed') ->firstOrFail(); } $project = Project::where('id', $projectId) ->where('state', 'enable') ->firstOrFail(); // 创建订单 $orderType = $orderId ? 'add_time' : 'normal'; $amounts = $this->calculateOrderAmount($userId, $addressId, $coachId, $projectId, $project->agent_id, $useBalance); $order = new Order(); $order->user_id = $userId; $order->project_id = $projectId; $order->address_id = $addressId; $order->coach_id = $coachId; $order->order_type = $orderType == 'normal' ? 0 : 1; $order->status = 0; $order->total_amount = $amounts['total_amount']; $order->balance_amount = $amounts['balance_amount']; $order->pay_amount = $amounts['pay_amount']; $order->coupon_amount = $amounts['coupon_amount']; $order->tip_amount = $amounts['tip_amount']; $order->project_amount = $amounts['project_amount']; $order->delivery_fee = $orderType == 'add_time' ? 0 : $amounts['delivery_fee']; $order->payment_type = $useBalance && $amounts['pay_amount'] == 0 ? 0 : 1; $order->save(); // 创建订单历史 if ($orderType == 'add_time') { OrderHistory::create([ 'order_id' => $order->id, 'type' => 'add_time', 'user_id' => $userId ]); } else { OrderHistory::create([ 'order_id' => $order->id, 'type' => 'create', 'user_id' => $userId ]); } // 余额支付处理 if ($order->payment_type == 0) { $order->status = 1; $order->save(); OrderHistory::create([ 'order_id' => $order->id, 'type' => 'pay', 'user_id' => $userId ]); CoachSchedule::create([ 'coach_id' => $coachId, 'date' => date('Y-m-d'), 'status' => 'busy' ]); return $order->id; } // 微信支付处理 // TODO: 调用支付接口 return $order->id; }); } /** * 加钟 */ public function addTime($userId, $orderId) { $order = Order::where('id', $orderId) ->where('user_id', $userId) ->firstOrFail(); return $this->createOrder($userId, $order->project_id, $order->address_id, $order->coach_id, 0, $orderId); } /** * 指定技师 */ public function assignCoach($userId, $orderId, $coachId) { return DB::transaction(function() use ($userId, $orderId, $coachId) { // 参数校验 $user = User::where('id', $userId) ->where('status', 1) ->firstOrFail(); $order = Order::where('id', $orderId) ->where('user_id', $userId) ->whereIn('status', [0, 1, 6]) ->firstOrFail(); $coach = CoachUser::where('id', $coachId) ->where('state', 'enable') ->where('auth_state', 'passed') ->firstOrFail(); $schedule = CoachSchedule::where('coach_id', $coachId) ->where('date', date('Y-m-d')) ->where('status', 'free') ->firstOrFail(); // 修改订单 $order->coach_id = $coachId; if ($order->status == 0) { $amounts = $this->calculateOrderAmount($userId, $order->address_id, $coachId, $order->project_id, $order->agent_id, $order->payment_type == 0); $order->total_amount = $amounts['total_amount']; $order->balance_amount = $amounts['balance_amount']; $order->pay_amount = $amounts['pay_amount']; $order->coupon_amount = $amounts['coupon_amount']; $order->tip_amount = $amounts['tip_amount']; $order->project_amount = $amounts['project_amount']; $order->delivery_fee = $amounts['delivery_fee']; if ($order->payment_type == 0) { $order->status = 1; } } if ($order->status == 1) { $order->status = 2; } $order->save(); // 创建订单历史 OrderHistory::create([ 'order_id' => $order->id, 'type' => 'assign_coach', 'user_id' => $userId, 'coach_id' => $coachId ]); OrderHistory::create([ 'order_id' => $order->id, 'type' => 'accept', 'user_id' => $userId, 'coach_id' => $coachId, 'remark' => '抢单成功' ]); // 更新抢单池 GrabOrder::where('order_id', $orderId) ->update(['status' => 2, 'coach_id' => $coachId]); // 更新排班 $schedule->status = 'busy'; $schedule->save(); return true; }); } }