|
@@ -5,9 +5,7 @@ namespace App\Services\Client;
|
|
use App\Models\AgentConfig;
|
|
use App\Models\AgentConfig;
|
|
use App\Models\AgentInfo;
|
|
use App\Models\AgentInfo;
|
|
use App\Models\CoachConfig;
|
|
use App\Models\CoachConfig;
|
|
-use App\Models\CoachSchedule;
|
|
|
|
use App\Models\CoachUser;
|
|
use App\Models\CoachUser;
|
|
-use App\Models\Coupon;
|
|
|
|
use App\Models\MemberUser;
|
|
use App\Models\MemberUser;
|
|
use App\Models\Order;
|
|
use App\Models\Order;
|
|
use App\Models\OrderGrabRecord;
|
|
use App\Models\OrderGrabRecord;
|
|
@@ -16,7 +14,6 @@ use App\Models\Project;
|
|
use App\Models\SysConfig;
|
|
use App\Models\SysConfig;
|
|
use App\Models\User;
|
|
use App\Models\User;
|
|
use App\Models\WalletRefundRecord;
|
|
use App\Models\WalletRefundRecord;
|
|
-use Carbon\Carbon;
|
|
|
|
use Exception;
|
|
use Exception;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\DB;
|
|
@@ -39,76 +36,74 @@ class OrderService
|
|
/**
|
|
/**
|
|
* 订单初始化
|
|
* 订单初始化
|
|
*/
|
|
*/
|
|
- public function initialize($userId, $data)
|
|
|
|
|
|
+ public function initialize(int $userId, array $data): array
|
|
{
|
|
{
|
|
- $user = MemberUser::find($userId);
|
|
|
|
|
|
+ try {
|
|
|
|
+ // 参数验证
|
|
|
|
+ abort_if(empty($data), 400, '订单初始化参数不能为空');
|
|
|
|
|
|
- if (! $user) {
|
|
|
|
- throw new Exception('用户不存在');
|
|
|
|
- }
|
|
|
|
|
|
+ DB::beginTransaction();
|
|
|
|
+ try {
|
|
|
|
+ $user = MemberUser::find($userId);
|
|
|
|
+ abort_if(! $user || $user->state != 'enable', 400, '用户状态异常');
|
|
|
|
|
|
- if ($user->state != 'enable') {
|
|
|
|
- throw new Exception('用户状态异常');
|
|
|
|
- }
|
|
|
|
|
|
+ // 查询用户钱包
|
|
|
|
+ $wallet = $user->wallet;
|
|
|
|
|
|
- // 查询用户钱包
|
|
|
|
- $wallet = $user->wallet;
|
|
|
|
-
|
|
|
|
- // 查询默认地址
|
|
|
|
- $address = $user->address;
|
|
|
|
-
|
|
|
|
- $areaCode = $address ? $address->area_code : $data['area_code'];
|
|
|
|
-
|
|
|
|
- // 查询技师数据
|
|
|
|
- $coach = CoachUser::where('state', 'enable')
|
|
|
|
- ->whereHas('info', function ($query) {
|
|
|
|
- $query->where('state', 'approved');
|
|
|
|
- })
|
|
|
|
- ->whereHas('real', function ($query) {
|
|
|
|
- $query->where('state', 'approved');
|
|
|
|
- })
|
|
|
|
- ->whereHas('qual', function ($query) {
|
|
|
|
- $query->where('state', 'approved');
|
|
|
|
- })
|
|
|
|
- ->with(['info:id,nickname,avatar,gender'])
|
|
|
|
- ->find($data['coach_id']);
|
|
|
|
-
|
|
|
|
- if (! $coach) {
|
|
|
|
- throw new Exception('技师不存在');
|
|
|
|
- }
|
|
|
|
|
|
+ // 查询默认地址
|
|
|
|
+ $address = $user->address;
|
|
|
|
|
|
- // 查询技师排班
|
|
|
|
- // $schedule = CoachSchedule::where('coach_id', $coachId)
|
|
|
|
- // ->where('date', date('Y-m-d'))
|
|
|
|
- // ->first();
|
|
|
|
|
|
+ $areaCode = $address ? $address->area_code : $data['area_code'];
|
|
|
|
|
|
- // // 查询用户优惠券
|
|
|
|
- // $coupons = Coupon::where('user_id', $userId)
|
|
|
|
- // ->where('state', 'enable')
|
|
|
|
- // ->where('expire_time', '>', now())
|
|
|
|
- // ->get();
|
|
|
|
|
|
+ // 查询技师数据
|
|
|
|
+ $coach = $this->validateCoach($data['coach_id']);
|
|
|
|
|
|
- // 获取项目详情
|
|
|
|
- $project = $this->projectService->getProjectDetail($data['project_id'], $areaCode);
|
|
|
|
|
|
+ // 查询技师排班
|
|
|
|
+ // $schedule = CoachSchedule::where('coach_id', $coachId)
|
|
|
|
+ // ->where('date', date('Y-m-d'))
|
|
|
|
+ // ->first();
|
|
|
|
|
|
- // 计算订单金额
|
|
|
|
- $amounts = $this->calculateOrderAmount($userId, $address?->id, $data['coach_id'], $data['project_id'], $project?->agent_id);
|
|
|
|
|
|
+ // // 查询用户优惠券
|
|
|
|
+ // $coupons = Coupon::where('user_id', $userId)
|
|
|
|
+ // ->where('state', 'enable')
|
|
|
|
+ // ->where('expire_time', '>', now())
|
|
|
|
+ // ->get();
|
|
|
|
|
|
- return [
|
|
|
|
- 'wallet' => $wallet,
|
|
|
|
- 'coach' => $coach,
|
|
|
|
- 'project' => $project,
|
|
|
|
- 'address' => $address,
|
|
|
|
- // 'schedule' => $schedule,
|
|
|
|
- 'amounts' => $amounts,
|
|
|
|
- // 'coupons' => $coupons
|
|
|
|
- ];
|
|
|
|
|
|
+ // 获取项目详情
|
|
|
|
+ $project = $this->projectService->getProjectDetail($data['project_id'], $areaCode);
|
|
|
|
+
|
|
|
|
+ // 计算订单金额
|
|
|
|
+ $amounts = $this->calculateOrderAmount($userId, $address?->id, $data['coach_id'], $data['project_id'], $project?->agent_id);
|
|
|
|
+
|
|
|
|
+ DB::commit();
|
|
|
|
+
|
|
|
|
+ return [
|
|
|
|
+ 'wallet' => $wallet,
|
|
|
|
+ 'coach' => $coach,
|
|
|
|
+ 'project' => $project,
|
|
|
|
+ 'address' => $address,
|
|
|
|
+ // 'schedule' => $schedule,
|
|
|
|
+ 'amounts' => $amounts,
|
|
|
|
+ // 'coupons' => $coupons
|
|
|
|
+ ];
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
+ DB::rollBack();
|
|
|
|
+ throw $e;
|
|
|
|
+ }
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
+ Log::error('订单初始化失败', [
|
|
|
|
+ 'userId' => $userId,
|
|
|
|
+ 'data' => $data,
|
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
|
+ ]);
|
|
|
|
+ throw $e;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 创建订单
|
|
* 创建订单
|
|
*/
|
|
*/
|
|
- public function createOrder($userId, array $data)
|
|
|
|
|
|
+ public function createOrder(int $userId, array $data): array
|
|
{
|
|
{
|
|
try {
|
|
try {
|
|
return DB::transaction(function () use ($userId, $data) {
|
|
return DB::transaction(function () use ($userId, $data) {
|
|
@@ -124,42 +119,26 @@ class OrderService
|
|
// 2. 创建订单
|
|
// 2. 创建订单
|
|
$orderType = isset($data['order_id']) ? 'add_time' : 'normal';
|
|
$orderType = isset($data['order_id']) ? 'add_time' : 'normal';
|
|
|
|
|
|
|
|
+ // 关键操作:验证必要参数
|
|
|
|
+ abort_if(empty($data['project_id']), 400, '项目ID不能为空');
|
|
|
|
+ abort_if(empty($data['service_time']), 400, '服务时间不能为空');
|
|
|
|
+ abort_if($orderType == 'normal' && empty($data['coach_id']), 400, '技师ID不能为空');
|
|
|
|
+ abort_if($orderType == 'normal' && empty($data['address_id']), 400, '地址ID不能为空');
|
|
|
|
+
|
|
if ($orderType == 'normal') {
|
|
if ($orderType == 'normal') {
|
|
|
|
+ // 普通订单验证技师
|
|
|
|
+ $coach = $this->validateCoach($data['coach_id']);
|
|
|
|
+ } else {
|
|
|
|
+ // 加钟订单验证
|
|
|
|
+ $originalOrder = $this->getOriginalOrder($user, $data['order_id']);
|
|
|
|
|
|
- // 查询技师及其认证状态
|
|
|
|
- $coach = CoachUser::where('id', $data['coach_id'])
|
|
|
|
- ->where('state', 'enable')
|
|
|
|
- ->whereHas('info', function ($query) {
|
|
|
|
- $query->where('state', 'approved');
|
|
|
|
- })
|
|
|
|
- ->whereHas('qual', function ($query) {
|
|
|
|
- $query->where('state', 'approved');
|
|
|
|
- })
|
|
|
|
- ->whereHas('real', function ($query) {
|
|
|
|
- $query->where('state', 'approved');
|
|
|
|
- })
|
|
|
|
- ->firstOrFail();
|
|
|
|
|
|
+ // 关键操作:验证原订单技师状态
|
|
|
|
+ $coach = $this->validateCoach($originalOrder->coach_id);
|
|
|
|
|
|
- } else {
|
|
|
|
- // 1. 检查原订单
|
|
|
|
- $originalOrder = $user->orders->where('id', $data['order_id'])
|
|
|
|
- ->whereIn('state', ['service_ing', 'service_end']) // 只有服务中和服务结束的订单可以加钟
|
|
|
|
- ->firstOrFail();
|
|
|
|
-
|
|
|
|
- // 2. 设置加钟订单的服务时间
|
|
|
|
- if ($originalOrder->state == 'service_ing') {
|
|
|
|
- // 服务中订单,加钟开始时间为原订单结束时间
|
|
|
|
- $startTime = now(); // Carbon::parse($originalOrder->service_time)->addMinutes($originalOrder->project->duration);
|
|
|
|
- } else {
|
|
|
|
- // 服务结束订单,加钟开始时间为当前时间
|
|
|
|
- $startTime = now();
|
|
|
|
- }
|
|
|
|
|
|
+ // 关键操作:验证原订单状态
|
|
|
|
+ abort_if(! in_array($originalOrder->state, ['service_ing', 'service_end']), 400, '原订单状态不允许加钟');
|
|
|
|
|
|
- // 3. 构建加钟订单数据
|
|
|
|
- $data['order_id'] = $data['order_id']; // 关联原订单ID
|
|
|
|
- $data['address_id'] = $originalOrder->address_id;
|
|
|
|
- $data['service_time'] = $startTime;
|
|
|
|
- $data['coach_id'] = $originalOrder->coach_id;
|
|
|
|
|
|
+ $data = $this->prepareAddTimeData($originalOrder, $data);
|
|
}
|
|
}
|
|
|
|
|
|
$address = $user->addresses()
|
|
$address = $user->addresses()
|
|
@@ -167,79 +146,23 @@ class OrderService
|
|
->firstOrFail();
|
|
->firstOrFail();
|
|
|
|
|
|
// 计算订单金额
|
|
// 计算订单金额
|
|
- $amounts = $this->calculateOrderAmount(
|
|
|
|
- $userId,
|
|
|
|
- $data['address_id'],
|
|
|
|
- $data['coach_id'],
|
|
|
|
- $data['project_id'],
|
|
|
|
- $project->agent_id,
|
|
|
|
- $data['use_balance'] ?? false
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
- $order = new Order;
|
|
|
|
-
|
|
|
|
- $order->user_id = $userId;
|
|
|
|
- $order->project_id = $data['project_id'];
|
|
|
|
- $order->coach_id = $data['coach_id'];
|
|
|
|
- $order->type = $orderType;
|
|
|
|
- $order->state = 'wait_pay';
|
|
|
|
- $order->source = 'platform';
|
|
|
|
- $order->total_amount = $amounts['total_amount'];
|
|
|
|
- $order->balance_amount = $amounts['balance_amount'];
|
|
|
|
- $order->pay_amount = $amounts['pay_amount'];
|
|
|
|
- $order->project_amount = $amounts['project_amount'];
|
|
|
|
- $order->traffic_amount = $orderType == 'add_time' ? 0 : $amounts['delivery_fee'];
|
|
|
|
- $order->payment_type = ($data['use_balance'] && $amounts['pay_amount'] == 0) ? 'balance' : null;
|
|
|
|
-
|
|
|
|
- $order->service_time = $data['service_time'];
|
|
|
|
-
|
|
|
|
- // 从用户地址获取位置信息
|
|
|
|
- $order->address_id = $data['address_id'];
|
|
|
|
- $order->longitude = $address->longitude; // 经度
|
|
|
|
- $order->latitude = $address->latitude; // 纬度
|
|
|
|
- $order->location = $address->location; // 定位地址
|
|
|
|
- $order->address = $address->address; // 详细地址
|
|
|
|
- $order->area_code = $address->area_code; // 行政区划代码
|
|
|
|
|
|
+ $amounts = $this->calculateOrderAmount($userId, $address->id, $data['coach_id'], $data['project_id'], $project->agent_id, $data['use_balance'] ?? false);
|
|
|
|
|
|
- $order->save();
|
|
|
|
|
|
+ // 关键操作:验证订单金额
|
|
|
|
+ abort_if($amounts['total_amount'] <= 0, 400, '订单金额异常');
|
|
|
|
|
|
- // 3. 创建订单记录
|
|
|
|
- OrderRecord::create([
|
|
|
|
- 'order_id' => $order->id,
|
|
|
|
- 'object_id' => $userId,
|
|
|
|
- 'object_type' => MemberUser::class,
|
|
|
|
- 'state' => $orderType == 'add_time' ? 'add_time' : 'create',
|
|
|
|
- 'remark' => $orderType == 'add_time' ? '加钟订单' : '创建订单',
|
|
|
|
- ]);
|
|
|
|
|
|
+ // 关键操作:验证余额支付
|
|
|
|
+ if ($amounts['payment_type'] == 'balance') {
|
|
|
|
+ $wallet = $user->wallet;
|
|
|
|
+ abort_if($wallet->available_balance < $amounts['balance_amount'], 400, '可用余额不足');
|
|
|
|
+ }
|
|
|
|
|
|
- // 4. 余额支付处理
|
|
|
|
|
|
+ // 创建订单记录
|
|
|
|
+ $order = $this->createOrderRecord($userId, $data, $orderType, $address, $amounts);
|
|
|
|
+
|
|
|
|
+ // 余额支付处理
|
|
if ($order->payment_type == 'balance') {
|
|
if ($order->payment_type == 'balance') {
|
|
- $order->state = $orderType == 'normal' ? 'wait_receive' : 'service_ing';
|
|
|
|
- $order->save();
|
|
|
|
-
|
|
|
|
- // 创建订单支付记录
|
|
|
|
- OrderRecord::create([
|
|
|
|
- 'order_id' => $order->id,
|
|
|
|
- 'object_id' => $userId,
|
|
|
|
- 'object_type' => MemberUser::class,
|
|
|
|
- 'state' => 'pay',
|
|
|
|
- 'remark' => '余额支付',
|
|
|
|
- ]);
|
|
|
|
-
|
|
|
|
- // 扣除用户钱包总余额
|
|
|
|
- $user->wallet->decrement('total_balance', $order->balance_amount);
|
|
|
|
- // 扣除用户钱包可用余额
|
|
|
|
- $user->wallet->decrement('available_balance', $order->balance_amount);
|
|
|
|
- $user->wallet->save();
|
|
|
|
-
|
|
|
|
- // 创建技师排班
|
|
|
|
- // CoachSchedule::create([
|
|
|
|
- // 'coach_id' => $data['coach_id'],
|
|
|
|
- // 'date' => date('Y-m-d'),
|
|
|
|
- // 'state' => 'busy',
|
|
|
|
- // ]);
|
|
|
|
-
|
|
|
|
- // TODO: 发送抢单通知
|
|
|
|
|
|
+ $this->handleBalancePayment($user, $order, $orderType);
|
|
}
|
|
}
|
|
|
|
|
|
return [
|
|
return [
|
|
@@ -257,146 +180,225 @@ class OrderService
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // 提取方法:验证技师
|
|
|
|
+ public function validateCoach(int $coachId): CoachUser
|
|
|
|
+ {
|
|
|
|
+ $coach = CoachUser::where('id', $coachId)
|
|
|
|
+ ->where('state', 'enable')
|
|
|
|
+ ->whereHas('info', fn ($q) => $q->where('state', 'approved'))
|
|
|
|
+ ->whereHas('qual', fn ($q) => $q->where('state', 'approved'))
|
|
|
|
+ ->whereHas('real', fn ($q) => $q->where('state', 'approved'))
|
|
|
|
+ ->firstOrFail();
|
|
|
|
+
|
|
|
|
+ return $coach;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 提取方法:获取原始订单
|
|
|
|
+ private function getOriginalOrder($user, $orderId): Order
|
|
|
|
+ {
|
|
|
|
+ $originalOrder = $user->orders->where('id', $orderId)
|
|
|
|
+ ->whereIn('state', ['service_ing', 'service_end'])
|
|
|
|
+ ->firstOrFail();
|
|
|
|
+
|
|
|
|
+ return $originalOrder;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 提取方法:准备加钟订单数据
|
|
|
|
+ private function prepareAddTimeData($originalOrder, $data): array
|
|
|
|
+ {
|
|
|
|
+ if ($originalOrder->state == 'service_ing') {
|
|
|
|
+ $startTime = now();
|
|
|
|
+ } else {
|
|
|
|
+ $startTime = now();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return [
|
|
|
|
+ ...$data,
|
|
|
|
+ 'order_id' => $data['order_id'],
|
|
|
|
+ 'address_id' => $originalOrder->address_id,
|
|
|
|
+ 'service_time' => $startTime,
|
|
|
|
+ 'coach_id' => $originalOrder->coach_id,
|
|
|
|
+ ];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 提取方法:创建订单记录
|
|
|
|
+ private function createOrderRecord($userId, $data, $orderType, $address, $amounts): Order
|
|
|
|
+ {
|
|
|
|
+ $order = new Order;
|
|
|
|
+ $order->user_id = $userId;
|
|
|
|
+ $order->project_id = $data['project_id'];
|
|
|
|
+ $order->coach_id = $data['coach_id'];
|
|
|
|
+ $order->type = $orderType;
|
|
|
|
+ $order->state = 'wait_pay';
|
|
|
|
+ $order->source = 'platform';
|
|
|
|
+ $order->total_amount = $amounts->total_amount;
|
|
|
|
+ $order->balance_amount = $amounts->balance_amount;
|
|
|
|
+ $order->pay_amount = $amounts->pay_amount;
|
|
|
|
+ $order->project_amount = $amounts->project_amount;
|
|
|
|
+ $order->traffic_amount = $orderType == 'add_time' ? 0 : $amounts->delivery_fee;
|
|
|
|
+ $order->payment_type = ($data['use_balance'] && $amounts->pay_amount == 0) ? 'balance' : null;
|
|
|
|
+ $order->service_time = $data['service_time'];
|
|
|
|
+ $order->address_id = $data['address_id'];
|
|
|
|
+ $order->longitude = $address->longitude;
|
|
|
|
+ $order->latitude = $address->latitude;
|
|
|
|
+ $order->location = $address->location;
|
|
|
|
+ $order->address = $address->address;
|
|
|
|
+ $order->area_code = $address->area_code;
|
|
|
|
+ $order->save();
|
|
|
|
+
|
|
|
|
+ OrderRecord::create([
|
|
|
|
+ 'order_id' => $order->id,
|
|
|
|
+ 'object_id' => $userId,
|
|
|
|
+ 'object_type' => MemberUser::class,
|
|
|
|
+ 'state' => $orderType == 'add_time' ? 'add_time' : 'create',
|
|
|
|
+ 'remark' => $orderType == 'add_time' ? '加钟订单' : '创建订单',
|
|
|
|
+ ]);
|
|
|
|
+
|
|
|
|
+ return $order;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 提取方法:处理余额支付
|
|
|
|
+ private function handleBalancePayment($user, $order, $orderType): void
|
|
|
|
+ {
|
|
|
|
+ $order->state = $orderType == 'normal' ? 'wait_receive' : 'service_ing';
|
|
|
|
+ $order->save();
|
|
|
|
+
|
|
|
|
+ OrderRecord::create([
|
|
|
|
+ 'order_id' => $order->id,
|
|
|
|
+ 'object_id' => $user->id,
|
|
|
|
+ 'object_type' => MemberUser::class,
|
|
|
|
+ 'state' => 'pay',
|
|
|
|
+ 'remark' => '余额支付',
|
|
|
|
+ ]);
|
|
|
|
+
|
|
|
|
+ $user->wallet->decrement('total_balance', $order->balance_amount);
|
|
|
|
+ $user->wallet->decrement('available_balance', $order->balance_amount);
|
|
|
|
+ $user->wallet->save();
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 取消订单
|
|
* 取消订单
|
|
*/
|
|
*/
|
|
- public function cancelOrder($userId, $orderId)
|
|
|
|
|
|
+ public function cancelOrder(int $userId, int $orderId): array
|
|
{
|
|
{
|
|
return DB::transaction(function () use ($userId, $orderId) {
|
|
return DB::transaction(function () use ($userId, $orderId) {
|
|
try {
|
|
try {
|
|
- $user = MemberUser::where('id', $userId)->firstOrFail();
|
|
|
|
- $order = $user->orders()->find($orderId);
|
|
|
|
-
|
|
|
|
- if (! $order) {
|
|
|
|
- throw new Exception('订单不存在');
|
|
|
|
- }
|
|
|
|
|
|
+ // 1. 验证用户和订单
|
|
|
|
+ $order = $this->validateOrderForCancel($userId, $orderId);
|
|
|
|
|
|
- // 判断订单状态
|
|
|
|
- if ($order->state == 'wait_receive') { // 已接单
|
|
|
|
- // 扣除20%费用
|
|
|
|
- $deductAmount = ($order->payment_amount + $order->balance_amount - $order->traffic_amount) * 0.2;
|
|
|
|
- $this->handleRefund($user, $order, $deductAmount, false);
|
|
|
|
- } elseif ($order->state == 'on_the_way') { // 已出发
|
|
|
|
- // 扣除50%费用并扣除路费
|
|
|
|
- $deductAmount = ($order->payment_amount + $order->balance_amount - $order->traffic_amount) * 0.5;
|
|
|
|
- $this->handleRefund($user, $order, $deductAmount, true);
|
|
|
|
- } elseif ($order->state == 'wait_pay') {
|
|
|
|
- // 待支付状态直接取消,无需退款
|
|
|
|
- } else {
|
|
|
|
- throw new Exception('当前订单状态不允许取消');
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // 添加订单取消记录
|
|
|
|
- OrderRecord::create([
|
|
|
|
- 'order_id' => $orderId,
|
|
|
|
- 'object_id' => $userId,
|
|
|
|
- 'object_type' => MemberUser::class,
|
|
|
|
- 'state' => 'cancel',
|
|
|
|
- 'remark' => '用户取消订单',
|
|
|
|
- ]);
|
|
|
|
|
|
+ // 2. 处理退款
|
|
|
|
+ $this->handleCancelRefund($order);
|
|
|
|
|
|
- // 修改订单状态
|
|
|
|
- $order->state = 'cancel';
|
|
|
|
- $order->save();
|
|
|
|
|
|
+ // 3. 完成订单取消
|
|
|
|
+ $this->completeCancel($order, $userId);
|
|
|
|
|
|
return ['message' => '订单已取消'];
|
|
return ['message' => '订单已取消'];
|
|
|
|
+
|
|
} catch (Exception $e) {
|
|
} catch (Exception $e) {
|
|
- Log::error('取消订单失败:', [
|
|
|
|
- 'message' => $e->getMessage(),
|
|
|
|
- 'user_id' => $userId,
|
|
|
|
- 'order_id' => $orderId,
|
|
|
|
- ]);
|
|
|
|
|
|
+ $this->logCancelOrderError($e, $userId, $orderId);
|
|
throw $e;
|
|
throw $e;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 验证订单取消条件
|
|
|
|
+ */
|
|
|
|
+ private function validateOrderForCancel(int $userId, int $orderId): Order
|
|
|
|
+ {
|
|
|
|
+ // 复用之前的用户验证逻辑
|
|
|
|
+ $user = MemberUser::where('id', $userId)
|
|
|
|
+ ->where('state', 'enable')
|
|
|
|
+ ->firstOrFail();
|
|
|
|
+
|
|
|
|
+ // 验证订单状态
|
|
|
|
+ $order = Order::where('user_id', $userId)
|
|
|
|
+ ->where('id', $orderId)
|
|
|
|
+ ->whereIn('state', ['wait_pay', 'wait_receive', 'on_the_way'])
|
|
|
|
+ ->lockForUpdate()
|
|
|
|
+ ->firstOrFail();
|
|
|
|
+
|
|
|
|
+ return $order;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 处理订单取消退款
|
|
|
|
+ */
|
|
|
|
+ private function handleCancelRefund(Order $order): void
|
|
|
|
+ {
|
|
|
|
+ $user = $order->user;
|
|
|
|
+
|
|
|
|
+ switch ($order->state) {
|
|
|
|
+ case 'wait_receive': // 已接单
|
|
|
|
+ // 扣除20%费用
|
|
|
|
+ $deductAmount = ($order->payment_amount + $order->balance_amount - $order->traffic_amount) * 0.2;
|
|
|
|
+ $this->handleRefund($user, $order, $deductAmount, false);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 'on_the_way': // 已出发
|
|
|
|
+ // 扣除50%费用并扣除路费
|
|
|
|
+ $deductAmount = ($order->payment_amount + $order->balance_amount - $order->traffic_amount) * 0.5;
|
|
|
|
+ $this->handleRefund($user, $order, $deductAmount, true);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 'wait_pay':
|
|
|
|
+ // 待支付状态直接取消,无需退款
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ abort(400, '当前订单状态不允许取消');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 完成订单取消
|
|
|
|
+ */
|
|
|
|
+ private function completeCancel(Order $order, int $userId): void
|
|
|
|
+ {
|
|
|
|
+ // 添加订单取消记录
|
|
|
|
+ OrderRecord::create([
|
|
|
|
+ 'order_id' => $order->id,
|
|
|
|
+ 'object_id' => $userId,
|
|
|
|
+ 'object_type' => MemberUser::class,
|
|
|
|
+ 'state' => 'cancel',
|
|
|
|
+ 'remark' => '用户取消订单',
|
|
|
|
+ ]);
|
|
|
|
+
|
|
|
|
+ // 修改订单状态
|
|
|
|
+ $order->state = 'cancel';
|
|
|
|
+ $order->cancel_time = now(); // 添加取消时间
|
|
|
|
+ $order->save();
|
|
|
|
+
|
|
|
|
+ // 如果有技师,可能需要通知技师订单已取消
|
|
|
|
+ if ($order->coach_id) {
|
|
|
|
+ // TODO: 发送通知给技师
|
|
|
|
+ // event(new OrderCancelledEvent($order));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 处理退款
|
|
* 处理退款
|
|
*/
|
|
*/
|
|
- private function handleRefund($user, $order, $deductAmount, $deductTrafficFee)
|
|
|
|
|
|
+ private function handleRefund(MemberUser $user, Order $order, float $deductAmount, bool $deductTrafficFee): void
|
|
{
|
|
{
|
|
- // 计算实际退款金额
|
|
|
|
|
|
+ // 关键操作:计算实际退款金额
|
|
$refundAmount = $order->payment_amount + $order->balance_amount;
|
|
$refundAmount = $order->payment_amount + $order->balance_amount;
|
|
if ($deductTrafficFee) {
|
|
if ($deductTrafficFee) {
|
|
$refundAmount -= $order->traffic_amount;
|
|
$refundAmount -= $order->traffic_amount;
|
|
- // 记录技师路费收入
|
|
|
|
- // ...
|
|
|
|
|
|
+ // TODO: 记录技师路费收入
|
|
}
|
|
}
|
|
$refundAmount -= $deductAmount;
|
|
$refundAmount -= $deductAmount;
|
|
|
|
|
|
// 优先从余额支付金额中扣除
|
|
// 优先从余额支付金额中扣除
|
|
$balanceRefund = min($order->balance_amount, $refundAmount);
|
|
$balanceRefund = min($order->balance_amount, $refundAmount);
|
|
if ($balanceRefund > 0) {
|
|
if ($balanceRefund > 0) {
|
|
-
|
|
|
|
- // 添加钱包退款记录
|
|
|
|
- $refundRecord = $user->wallet->refundRecords()->create([
|
|
|
|
- 'refund_method' => 'balance',
|
|
|
|
- 'total_refund_amount' => $order->payment_amount + $order->balance_amount,
|
|
|
|
- 'actual_refund_amount' => '0.00',
|
|
|
|
- 'wallet_balance_refund_amount' => $balanceRefund,
|
|
|
|
- 'recharge_balance_refund_amount' => '0.00',
|
|
|
|
- 'remark' => '订单取消退还余额',
|
|
|
|
- 'order_id' => $order->id,
|
|
|
|
- ]);
|
|
|
|
-
|
|
|
|
- // 添加钱包交易记录
|
|
|
|
- $user->wallet->transRecords()->create([
|
|
|
|
- 'amount' => $balanceRefund,
|
|
|
|
- 'owner_type' => $refundRecord::class,
|
|
|
|
- 'owner_id' => $refundRecord->id,
|
|
|
|
- 'remark' => '订单取消退还余额',
|
|
|
|
- 'trans_type' => 'income',
|
|
|
|
- 'storage_type' => 'balance',
|
|
|
|
- 'amount' => $balanceRefund,
|
|
|
|
- 'before_balance' => $user->wallet->total_balance,
|
|
|
|
- 'after_balance' => $user->wallet->total_balance + $balanceRefund,
|
|
|
|
- 'before_recharge_balance' => '0.00',
|
|
|
|
- 'after_recharge_balance' => '0.00',
|
|
|
|
- 'trans_time' => now(),
|
|
|
|
- 'state' => 'success',
|
|
|
|
- ]);
|
|
|
|
-
|
|
|
|
- $user->wallet->increment('total_balance', $balanceRefund);
|
|
|
|
- $user->wallet->increment('available_balance', $balanceRefund);
|
|
|
|
- $user->wallet->save();
|
|
|
|
|
|
+ $this->createRefundRecords($user, $order, $balanceRefund);
|
|
}
|
|
}
|
|
|
|
|
|
// 剩余退款金额从支付金额中退还
|
|
// 剩余退款金额从支付金额中退还
|
|
$paymentRefund = $refundAmount - $balanceRefund;
|
|
$paymentRefund = $refundAmount - $balanceRefund;
|
|
if ($paymentRefund > 0) {
|
|
if ($paymentRefund > 0) {
|
|
-
|
|
|
|
- // 添加钱包退款记录
|
|
|
|
- $refundRecord = $user->wallet->refundRecords()->create([
|
|
|
|
- 'refund_method' => 'balance',
|
|
|
|
- 'total_refund_amount' => $order->payment_amount + $order->balance_amount,
|
|
|
|
- 'actual_refund_amount' => '0.00',
|
|
|
|
- 'wallet_balance_refund_amount' => $balanceRefund,
|
|
|
|
- 'recharge_balance_refund_amount' => '0.00',
|
|
|
|
- 'remark' => '订单取消退还余额',
|
|
|
|
- 'order_id' => $order->id,
|
|
|
|
- ]);
|
|
|
|
-
|
|
|
|
- // 添加钱包交易记录
|
|
|
|
- $user->wallet->transRecords()->create([
|
|
|
|
- 'amount' => $balanceRefund,
|
|
|
|
- 'owner_type' => $refundRecord::class,
|
|
|
|
- 'owner_id' => $refundRecord->id,
|
|
|
|
- 'remark' => '订单取消退还余额',
|
|
|
|
- 'trans_type' => 'income',
|
|
|
|
- 'storage_type' => 'balance',
|
|
|
|
- 'amount' => $balanceRefund,
|
|
|
|
- 'before_balance' => $user->wallet->total_balance,
|
|
|
|
- 'after_balance' => $user->wallet->total_balance + $balanceRefund,
|
|
|
|
- 'before_recharge_balance' => '0.00',
|
|
|
|
- 'after_recharge_balance' => '0.00',
|
|
|
|
- 'trans_time' => now(),
|
|
|
|
- 'state' => 'success',
|
|
|
|
- ]);
|
|
|
|
-
|
|
|
|
- $user->wallet->increment('total_balance', $paymentRefund);
|
|
|
|
- $user->wallet->increment('available_balance', $paymentRefund);
|
|
|
|
- $user->wallet->save();
|
|
|
|
|
|
+ $this->createRefundRecords($user, $order, $paymentRefund, 'payment');
|
|
}
|
|
}
|
|
|
|
|
|
// 记录平台收入
|
|
// 记录平台收入
|
|
@@ -406,52 +408,161 @@ class OrderService
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 创建退款记录
|
|
|
|
+ */
|
|
|
|
+ private function createRefundRecords($user, $order, $amount, $type = 'balance'): void
|
|
|
|
+ {
|
|
|
|
+ $refundMethod = $type;
|
|
|
|
+ $remark = $type == 'balance' ? '订单取消退还余额' : '订单取消退还支付金额';
|
|
|
|
+
|
|
|
|
+ // 创建退款记录
|
|
|
|
+ $refundRecord = $user->wallet->refundRecords()->create([
|
|
|
|
+ 'refund_method' => $refundMethod,
|
|
|
|
+ 'total_refund_amount' => $order->payment_amount + $order->balance_amount,
|
|
|
|
+ 'actual_refund_amount' => '0.00',
|
|
|
|
+ 'wallet_balance_refund_amount' => $type == 'balance' ? $amount : '0.00',
|
|
|
|
+ 'recharge_balance_refund_amount' => '0.00',
|
|
|
|
+ 'remark' => $remark,
|
|
|
|
+ 'order_id' => $order->id,
|
|
|
|
+ ]);
|
|
|
|
+
|
|
|
|
+ // 创建交易记录
|
|
|
|
+ $user->wallet->transRecords()->create([
|
|
|
|
+ 'amount' => $amount,
|
|
|
|
+ 'owner_type' => get_class($refundRecord),
|
|
|
|
+ 'owner_id' => $refundRecord->id,
|
|
|
|
+ 'remark' => $remark,
|
|
|
|
+ 'trans_type' => 'income',
|
|
|
|
+ 'storage_type' => 'balance',
|
|
|
|
+ 'before_balance' => $user->wallet->total_balance,
|
|
|
|
+ 'after_balance' => $user->wallet->total_balance + $amount,
|
|
|
|
+ 'before_recharge_balance' => '0.00',
|
|
|
|
+ 'after_recharge_balance' => '0.00',
|
|
|
|
+ 'trans_time' => now(),
|
|
|
|
+ 'state' => 'success',
|
|
|
|
+ ]);
|
|
|
|
+
|
|
|
|
+ // 更新钱包余额
|
|
|
|
+ $user->wallet->increment('total_balance', $amount);
|
|
|
|
+ $user->wallet->increment('available_balance', $amount);
|
|
|
|
+ $user->wallet->save();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 记录订单取消错误日志
|
|
|
|
+ */
|
|
|
|
+ private function logCancelOrderError(Exception $e, int $userId, int $orderId): void
|
|
|
|
+ {
|
|
|
|
+ // 复用之前的日志记录方法
|
|
|
|
+ Log::error('取消订单失败:', [
|
|
|
|
+ 'message' => $e->getMessage(),
|
|
|
|
+ 'user_id' => $userId,
|
|
|
|
+ 'order_id' => $orderId,
|
|
|
|
+ 'trace' => $e->getTraceAsString(),
|
|
|
|
+ ]);
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 结束订单
|
|
* 结束订单
|
|
*/
|
|
*/
|
|
- public function finishOrder($userId, $orderId)
|
|
|
|
|
|
+ public function finishOrder(int $userId, int $orderId): array
|
|
{
|
|
{
|
|
return DB::transaction(function () use ($userId, $orderId) {
|
|
return DB::transaction(function () use ($userId, $orderId) {
|
|
try {
|
|
try {
|
|
- // 1. 参数校验
|
|
|
|
- $order = Order::where('user_id', $userId)
|
|
|
|
- ->where('id', $orderId)
|
|
|
|
- ->where('state', 'service_ing') // 订单状态必须是服务中
|
|
|
|
- ->firstOrFail();
|
|
|
|
|
|
+ // 1. 验证用户和订单
|
|
|
|
+ $order = $this->validateOrderForFinish($userId, $orderId);
|
|
|
|
|
|
- if (! $order) {
|
|
|
|
- throw new Exception('订单不能结束');
|
|
|
|
- }
|
|
|
|
|
|
+ // 2. 验证技师状态
|
|
|
|
+ $this->validateCoach($order->coach_id);
|
|
|
|
|
|
- // 2. 创建订单历史记录
|
|
|
|
- OrderRecord::create([
|
|
|
|
- 'order_id' => $orderId,
|
|
|
|
- 'object_id' => $userId,
|
|
|
|
- 'object_type' => MemberUser::class,
|
|
|
|
- 'state' => 'finish',
|
|
|
|
- 'remark' => '服务完成',
|
|
|
|
- ]);
|
|
|
|
|
|
+ // 3. 验证服务时长
|
|
|
|
+ $this->validateServiceDuration($order);
|
|
|
|
|
|
- // 3. 修改订单状态为服务结束
|
|
|
|
- $order->state = 'service_end';
|
|
|
|
- $order->save();
|
|
|
|
|
|
+ // 4. 完成订单
|
|
|
|
+ $this->completeOrder($order, $userId);
|
|
|
|
|
|
return ['message' => '订单已完成'];
|
|
return ['message' => '订单已完成'];
|
|
|
|
+
|
|
} catch (Exception $e) {
|
|
} catch (Exception $e) {
|
|
- Log::error('结束订单失败:', [
|
|
|
|
- 'message' => $e->getMessage(),
|
|
|
|
- 'user_id' => $userId,
|
|
|
|
- 'order_id' => $orderId,
|
|
|
|
- ]);
|
|
|
|
|
|
+ $this->logFinishOrderError($e, $userId, $orderId);
|
|
throw $e;
|
|
throw $e;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 验证订单完成条件
|
|
|
|
+ */
|
|
|
|
+ private function validateOrderForFinish(int $userId, int $orderId): Order
|
|
|
|
+ {
|
|
|
|
+ // 验证用户状态
|
|
|
|
+ $user = MemberUser::where('id', $userId)
|
|
|
|
+ ->where('state', 'enable')
|
|
|
|
+ ->firstOrFail();
|
|
|
|
+
|
|
|
|
+ // 验证订单状态
|
|
|
|
+ $order = Order::where('user_id', $userId)
|
|
|
|
+ ->where('id', $orderId)
|
|
|
|
+ ->where('state', 'service_ing')
|
|
|
|
+ ->lockForUpdate()
|
|
|
|
+ ->firstOrFail();
|
|
|
|
+
|
|
|
|
+ return $order;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 验证服务时长
|
|
|
|
+ */
|
|
|
|
+ private function validateServiceDuration(Order $order): void
|
|
|
|
+ {
|
|
|
|
+ // 计算服务时长
|
|
|
|
+ $serviceStartTime = $order->service_start_time ?? $order->created_at;
|
|
|
|
+ $serviceDuration = now()->diffInMinutes($serviceStartTime);
|
|
|
|
+
|
|
|
|
+ // 获取项目要求的最短服务时长
|
|
|
|
+ $minDuration = $order->project->duration ?? 0;
|
|
|
|
+
|
|
|
|
+ abort_if($serviceDuration < $minDuration, 400, "服务时长不足{$minDuration}分钟");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 完成订单
|
|
|
|
+ */
|
|
|
|
+ private function completeOrder(Order $order, int $userId): void
|
|
|
|
+ {
|
|
|
|
+ // 1. 创建订单记录
|
|
|
|
+ OrderRecord::create([
|
|
|
|
+ 'order_id' => $order->id,
|
|
|
|
+ 'object_id' => $userId,
|
|
|
|
+ 'object_type' => MemberUser::class,
|
|
|
|
+ 'state' => 'finish',
|
|
|
|
+ 'remark' => '服务完成',
|
|
|
|
+ ]);
|
|
|
|
+
|
|
|
|
+ // 2. 更新订单状态
|
|
|
|
+ $order->state = 'service_end';
|
|
|
|
+ $order->finish_time = now();
|
|
|
|
+ $order->save();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 记录订单完成错误日志
|
|
|
|
+ */
|
|
|
|
+ private function logFinishOrderError(Exception $e, int $userId, int $orderId): void
|
|
|
|
+ {
|
|
|
|
+ Log::error('结束订单失败:', [
|
|
|
|
+ 'message' => $e->getMessage(),
|
|
|
|
+ 'user_id' => $userId,
|
|
|
|
+ 'order_id' => $orderId,
|
|
|
|
+ 'trace' => $e->getTraceAsString(),
|
|
|
|
+ ]);
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 确认技师离开
|
|
* 确认技师离开
|
|
*/
|
|
*/
|
|
- public function confirmLeave($userId, $orderId)
|
|
|
|
|
|
+ public function confirmLeave(int $userId, int $orderId): array
|
|
{
|
|
{
|
|
return DB::transaction(function () use ($userId, $orderId) {
|
|
return DB::transaction(function () use ($userId, $orderId) {
|
|
try {
|
|
try {
|
|
@@ -474,11 +585,11 @@ class OrderService
|
|
'remark' => '技师已离开',
|
|
'remark' => '技师已离开',
|
|
]);
|
|
]);
|
|
|
|
|
|
- // 3. 修��订单状态为撤离
|
|
|
|
|
|
+ // 3. 修改订单状态为撤离
|
|
$order->state = 'leave';
|
|
$order->state = 'leave';
|
|
$order->save();
|
|
$order->save();
|
|
|
|
|
|
- return ['message' => '已确认技师离开'];
|
|
|
|
|
|
+ return ['message' => '已确技师离开'];
|
|
} catch (Exception $e) {
|
|
} catch (Exception $e) {
|
|
Log::error('确认技师离开失败:', [
|
|
Log::error('确认技师离开失败:', [
|
|
'message' => $e->getMessage(),
|
|
'message' => $e->getMessage(),
|
|
@@ -493,7 +604,7 @@ class OrderService
|
|
/**
|
|
/**
|
|
* 获取订单列表
|
|
* 获取订单列表
|
|
*/
|
|
*/
|
|
- public function getOrderList($user_id)
|
|
|
|
|
|
+ public function getOrderList(int $user_id): \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
|
{
|
|
{
|
|
$user = MemberUser::find($user_id);
|
|
$user = MemberUser::find($user_id);
|
|
|
|
|
|
@@ -508,7 +619,7 @@ class OrderService
|
|
/**
|
|
/**
|
|
* 获取订单详情
|
|
* 获取订单详情
|
|
*/
|
|
*/
|
|
- public function getOrderDetail($userId, $orderId)
|
|
|
|
|
|
+ public function getOrderDetail(int $userId, int $orderId): Order
|
|
{
|
|
{
|
|
$user = MemberUser::find($userId);
|
|
$user = MemberUser::find($userId);
|
|
|
|
|
|
@@ -524,14 +635,15 @@ class OrderService
|
|
/**
|
|
/**
|
|
* 订单退款
|
|
* 订单退款
|
|
*/
|
|
*/
|
|
- public function refundOrder($orderId)
|
|
|
|
|
|
+ public function refundOrder(int $orderId): array
|
|
{
|
|
{
|
|
- $userId = Auth::id();
|
|
|
|
|
|
+ // 使用 Auth::user() 获取用户对象
|
|
|
|
+ $user = Auth::user();
|
|
|
|
|
|
- return DB::transaction(function () use ($orderId, $userId) {
|
|
|
|
|
|
+ return DB::transaction(function () use ($orderId, $user) {
|
|
// 查询并锁定订单
|
|
// 查询并锁定订单
|
|
$order = Order::where('id', $orderId)
|
|
$order = Order::where('id', $orderId)
|
|
- ->where('user_id', $userId)
|
|
|
|
|
|
+ ->where('user_id', $user->id)
|
|
->where('state', 'pending')
|
|
->where('state', 'pending')
|
|
->lockForUpdate()
|
|
->lockForUpdate()
|
|
->firstOrFail();
|
|
->firstOrFail();
|
|
@@ -543,7 +655,7 @@ class OrderService
|
|
// 添加订单记录
|
|
// 添加订单记录
|
|
OrderRecord::create([
|
|
OrderRecord::create([
|
|
'order_id' => $orderId,
|
|
'order_id' => $orderId,
|
|
- 'object_id' => $userId,
|
|
|
|
|
|
+ 'object_id' => $user->id,
|
|
'object_type' => 'user',
|
|
'object_type' => 'user',
|
|
'state' => 'refund',
|
|
'state' => 'refund',
|
|
'remark' => '订单退款',
|
|
'remark' => '订单退款',
|
|
@@ -552,7 +664,7 @@ class OrderService
|
|
// 创建退款记录
|
|
// 创建退款记录
|
|
WalletRefundRecord::create([
|
|
WalletRefundRecord::create([
|
|
'order_id' => $orderId,
|
|
'order_id' => $orderId,
|
|
- 'user_id' => $userId,
|
|
|
|
|
|
+ 'user_id' => $user->id,
|
|
'amount' => $order->total_amount,
|
|
'amount' => $order->total_amount,
|
|
'state' => 'success',
|
|
'state' => 'success',
|
|
]);
|
|
]);
|
|
@@ -564,7 +676,7 @@ class OrderService
|
|
/**
|
|
/**
|
|
* 获取代理商配置
|
|
* 获取代理商配置
|
|
*/
|
|
*/
|
|
- public function getAgentConfig($agentId)
|
|
|
|
|
|
+ public function getAgentConfig(int $agentId): array
|
|
{
|
|
{
|
|
$agent = AgentInfo::where('id', $agentId)
|
|
$agent = AgentInfo::where('id', $agentId)
|
|
->where('state', 'enable')
|
|
->where('state', 'enable')
|
|
@@ -582,7 +694,7 @@ class OrderService
|
|
/**
|
|
/**
|
|
* 获取技师配置
|
|
* 获取技师配置
|
|
*/
|
|
*/
|
|
- public function getCoachConfig($coachId)
|
|
|
|
|
|
+ public function getCoachConfig(int $coachId): array
|
|
{
|
|
{
|
|
$coach = CoachUser::where('id', $coachId)
|
|
$coach = CoachUser::where('id', $coachId)
|
|
->where('state', 'enable')
|
|
->where('state', 'enable')
|
|
@@ -599,257 +711,350 @@ class OrderService
|
|
|
|
|
|
/**
|
|
/**
|
|
* 计算路费金额
|
|
* 计算路费金额
|
|
|
|
+ *
|
|
|
|
+ * @param int $coachId 技师ID
|
|
|
|
+ * @param int $projectId 项目ID
|
|
|
|
+ * @param int|null $agentId 代理商ID
|
|
|
|
+ * @param float $distance 距离(公里)
|
|
|
|
+ * @return float 路费金额
|
|
|
|
+ *
|
|
|
|
+ * @throws Exception
|
|
*/
|
|
*/
|
|
- public function calculateDeliveryFee($coachId, $projectId, $agentId, $distance)
|
|
|
|
- {
|
|
|
|
-
|
|
|
|
- // 查询技师数据
|
|
|
|
- $coach = CoachUser::where('state', 'enable')
|
|
|
|
- ->whereHas('info', function ($query) {
|
|
|
|
- $query->where('state', 'approved');
|
|
|
|
- })
|
|
|
|
- ->whereHas('real', function ($query) {
|
|
|
|
- $query->where('state', 'approved');
|
|
|
|
- })
|
|
|
|
- ->whereHas('qual', function ($query) {
|
|
|
|
- $query->where('state', 'approved');
|
|
|
|
- })
|
|
|
|
- ->find($coachId);
|
|
|
|
-
|
|
|
|
- if (! $coach) {
|
|
|
|
- throw new Exception('技师不存在');
|
|
|
|
- }
|
|
|
|
|
|
+ public function calculateDeliveryFee(
|
|
|
|
+ int $coachId,
|
|
|
|
+ int $projectId,
|
|
|
|
+ ?int $agentId,
|
|
|
|
+ float $distance
|
|
|
|
+ ): float {
|
|
|
|
+ try {
|
|
|
|
+ // 1. 校验技师
|
|
|
|
+ $coach = CoachUser::where('state', 'enable')
|
|
|
|
+ ->whereHas('info', fn ($q) => $q->where('state', 'approved'))
|
|
|
|
+ ->whereHas('real', fn ($q) => $q->where('state', 'approved'))
|
|
|
|
+ ->whereHas('qual', fn ($q) => $q->where('state', 'approved'))
|
|
|
|
+ ->with(['projects' => fn ($q) => $q->where('project_id', $projectId)])
|
|
|
|
+ ->find($coachId);
|
|
|
|
|
|
- // 查询技师项目
|
|
|
|
- $coachProject = $coach->projects()
|
|
|
|
- ->where('state', 'enable')
|
|
|
|
- ->where('project_id', $projectId)
|
|
|
|
- ->first();
|
|
|
|
- if (! $coachProject) {
|
|
|
|
- throw new Exception('项目不存在');
|
|
|
|
- }
|
|
|
|
|
|
+ abort_if(! $coach, 404, '技师不存在或状态异常');
|
|
|
|
|
|
- // 技师免收路费
|
|
|
|
- if ($coachProject->traffic_fee_type == 'free') {
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
|
|
+ // 2. 校验技师项目
|
|
|
|
+ $coachProject = $coach->projects->first();
|
|
|
|
|
|
- // 查询代理商
|
|
|
|
- $agent = AgentInfo::where('state', 'enable')->find($agentId);
|
|
|
|
- if ($agent) {
|
|
|
|
- $agentProject = $agent->projects()
|
|
|
|
- ->where('state', 'enable')
|
|
|
|
- ->where('project_id', $projectId)
|
|
|
|
- ->first();
|
|
|
|
|
|
+ abort_if(! $coachProject, 404, '技师项目不存在');
|
|
|
|
|
|
- if (! $agentProject) {
|
|
|
|
- throw new Exception('代理商项目不存在');
|
|
|
|
|
|
+ // 3. 判断是否免收路费
|
|
|
|
+ if ($coachProject->traffic_fee_type == 'free') {
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
- $config = $agent->projectConfig;
|
|
|
|
|
|
|
|
- } else {
|
|
|
|
- // 系统配置
|
|
|
|
- $config = SysConfig::where('key', 'delivery_fee')->firstOrFail();
|
|
|
|
- dd('暂停处理');
|
|
|
|
- }
|
|
|
|
|
|
+ // 4. 获取路费配置
|
|
|
|
+ $config = $this->getDeliveryFeeConfig($agentId);
|
|
|
|
|
|
- $fee = 0;
|
|
|
|
- if ($distance <= $config->min_distance) {
|
|
|
|
- $fee = $config->min_fee;
|
|
|
|
- } else {
|
|
|
|
- $extraDistance = $distance - $config->min_distance;
|
|
|
|
- $fee = $config->min_fee + ($extraDistance * $config->per_km_fee);
|
|
|
|
- }
|
|
|
|
|
|
+ abort_if(! $config, 404, '路费配置不存在');
|
|
|
|
+
|
|
|
|
+ // 5. 计算路费
|
|
|
|
+ $fee = $this->calculateFee($distance, $config);
|
|
|
|
+
|
|
|
|
+ // 6. 判断是否往返
|
|
|
|
+ return $coachProject->delivery_fee_type == 'round_trip'
|
|
|
|
+ ? bcmul($fee, '2', 2)
|
|
|
|
+ : $fee;
|
|
|
|
|
|
- return $coachProject->delivery_fee_type == 'round_trip' ? $fee * 2 : $fee;
|
|
|
|
|
|
+ } catch (Exception $e) {
|
|
|
|
+ Log::error(__CLASS__.'->'.__FUNCTION__.'计算路费失败:', [
|
|
|
|
+ 'message' => $e->getMessage(),
|
|
|
|
+ 'coach_id' => $coachId,
|
|
|
|
+ 'project_id' => $projectId,
|
|
|
|
+ 'agent_id' => $agentId,
|
|
|
|
+ 'distance' => $distance,
|
|
|
|
+ 'trace' => $e->getTraceAsString(),
|
|
|
|
+ ]);
|
|
|
|
+ throw $e;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 计算订单金额
|
|
|
|
|
|
+ * 获取路费配置
|
|
*/
|
|
*/
|
|
- public function calculateOrderAmount($userId, $addressId, $coachId, $projectId, $agentId, $useBalance = false)
|
|
|
|
|
|
+ private function getDeliveryFeeConfig(?int $agentId): ?object
|
|
{
|
|
{
|
|
- // 参数校验
|
|
|
|
- $user = MemberUser::find($userId);
|
|
|
|
- if (! $user) {
|
|
|
|
- throw new Exception('用户不存在');
|
|
|
|
|
|
+ // 优先获取代理商配置
|
|
|
|
+ if ($agentId) {
|
|
|
|
+ $agent = AgentInfo::where('state', 'enable')
|
|
|
|
+ ->with(['projectConfig'])
|
|
|
|
+ ->find($agentId);
|
|
|
|
+
|
|
|
|
+ if ($agent && $agent->projectConfig) {
|
|
|
|
+ return $agent->projectConfig;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- if ($user->state != 'enable') {
|
|
|
|
- throw new Exception('用户状态异常');
|
|
|
|
- }
|
|
|
|
|
|
+ // 获取系统配置
|
|
|
|
+ return SysConfig::where('key', 'delivery_fee')->first();
|
|
|
|
+ }
|
|
|
|
|
|
- // 查询地址
|
|
|
|
- $address = $user->address()->find($addressId);
|
|
|
|
-
|
|
|
|
- // 查询技师数据
|
|
|
|
- $coach = CoachUser::where('state', 'enable')
|
|
|
|
- ->whereHas('info', function ($query) {
|
|
|
|
- $query->where('state', 'approved');
|
|
|
|
- })
|
|
|
|
- ->whereHas('real', function ($query) {
|
|
|
|
- $query->where('state', 'approved');
|
|
|
|
- })
|
|
|
|
- ->whereHas('qual', function ($query) {
|
|
|
|
- $query->where('state', 'approved');
|
|
|
|
- })
|
|
|
|
- ->with(['info:id,nickname,avatar,gender'])
|
|
|
|
- ->find($coachId);
|
|
|
|
-
|
|
|
|
- if (! $coach) {
|
|
|
|
- throw new Exception('技师不存在');
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 计算路费
|
|
|
|
+ */
|
|
|
|
+ private function calculateFee(float $distance, object $config): float
|
|
|
|
+ {
|
|
|
|
+ // 最小距离内按起步价计算
|
|
|
|
+ if ($distance <= $config->min_distance) {
|
|
|
|
+ return (float) $config->min_fee;
|
|
}
|
|
}
|
|
|
|
|
|
- // 查询技师项目
|
|
|
|
- $coachProject = $coach->projects()
|
|
|
|
- ->where('state', 'enable')
|
|
|
|
- ->where('project_id', $projectId)
|
|
|
|
- ->first();
|
|
|
|
- if (! $coachProject) {
|
|
|
|
- throw new Exception('项目不存在');
|
|
|
|
- }
|
|
|
|
|
|
+ // 超出最小距离部分按每公里费用计算
|
|
|
|
+ $extraDistance = bcsub($distance, $config->min_distance, 2);
|
|
|
|
+ $extraFee = bcmul($extraDistance, $config->per_km_fee, 2);
|
|
|
|
|
|
- // 查询项目
|
|
|
|
- $project = $coachProject->basicInfo;
|
|
|
|
|
|
+ return bcadd($config->min_fee, $extraFee, 2);
|
|
|
|
+ }
|
|
|
|
|
|
- if (! $project) {
|
|
|
|
- throw new Exception('项目不存在');
|
|
|
|
- }
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 计算订单金额
|
|
|
|
+ *
|
|
|
|
+ * @param int $userId 用户ID
|
|
|
|
+ * @param int $addressId 地址ID
|
|
|
|
+ * @param int $coachId 技师ID
|
|
|
|
+ * @param int $projectId 项目ID
|
|
|
|
+ * @param int $agentId 代理商ID
|
|
|
|
+ * @param bool $useBalance 是否使用余额
|
|
|
|
+ * @param float $distance 距离
|
|
|
|
+ *
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ public function calculateOrderAmount(
|
|
|
|
+ int $userId,
|
|
|
|
+ int $addressId,
|
|
|
|
+ int $coachId,
|
|
|
|
+ int $projectId,
|
|
|
|
+ ?int $agentId = null,
|
|
|
|
+ bool $useBalance = false,
|
|
|
|
+ float $distance = 0
|
|
|
|
+ ): array {
|
|
|
|
+ try {
|
|
|
|
+ // 1. 参数校验
|
|
|
|
+ $user = MemberUser::find($userId);
|
|
|
|
+ abort_if(! $user || $user->state != 'enable', 404, '用户不存在或状态异常');
|
|
|
|
|
|
- if ($project->state != 'enable') {
|
|
|
|
- throw new Exception('项目状态异常');
|
|
|
|
- }
|
|
|
|
|
|
+ // 2. 查询技师项目
|
|
|
|
+ $coach = $this->validateCoach($coachId);
|
|
|
|
+
|
|
|
|
+ abort_if(! $coach, 404, '技师不存在或状态异常');
|
|
|
|
|
|
- // 查询代理商
|
|
|
|
- $agent = AgentInfo::where('state', 'enable')->find($agentId);
|
|
|
|
- if ($agent) {
|
|
|
|
- $agentProject = $agent->projects()
|
|
|
|
|
|
+ $coachProject = $coach->projects()
|
|
->where('state', 'enable')
|
|
->where('state', 'enable')
|
|
->where('project_id', $projectId)
|
|
->where('project_id', $projectId)
|
|
->first();
|
|
->first();
|
|
|
|
|
|
- if (! $agentProject) {
|
|
|
|
- throw new Exception('代理商项目不在');
|
|
|
|
|
|
+ abort_if(! $coachProject, 404, '技师项目不存在');
|
|
|
|
+
|
|
|
|
+ // 3. 查询基础项目
|
|
|
|
+ $project = Project::where('id', $projectId)
|
|
|
|
+ ->where('state', 'enable')
|
|
|
|
+ ->first();
|
|
|
|
+
|
|
|
|
+ abort_if(! $project, 404, '项目不存在或状态异常');
|
|
|
|
+
|
|
|
|
+ // 4. 计算距离
|
|
|
|
+ if ($distance <= 0) {
|
|
|
|
+ $address = $user->addresses()->findOrFail($addressId);
|
|
|
|
+ $coachService = app(CoachService::class);
|
|
|
|
+ $coachDetail = $coachService->getCoachDetail($coachId, $address->latitude, $address->longitude);
|
|
|
|
+ $distance = $coachDetail['distance'] ?? 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 5. 获取项目价格
|
|
|
|
+ $projectAmount = $this->getProjectPrice($project, $agentId, $projectId);
|
|
|
|
+
|
|
|
|
+ // 6. 计算路费
|
|
|
|
+ $deliveryFee = $this->calculateDeliveryFee($coachId, $projectId, $agentId, $distance);
|
|
|
|
+
|
|
|
|
+ // 7. 计算优惠券金额
|
|
|
|
+ $couponAmount = $this->calculateCouponAmount();
|
|
|
|
+
|
|
|
|
+ // 8. 计算总金额
|
|
|
|
+ $totalAmount = bcadd($projectAmount, $deliveryFee, 2);
|
|
|
|
+ $totalAmount = bcsub($totalAmount, $couponAmount, 2);
|
|
|
|
+ $totalAmount = max(0, $totalAmount);
|
|
|
|
+
|
|
|
|
+ // 9. 计算余额支付金额
|
|
|
|
+ $balanceAmount = 0;
|
|
|
|
+ $payAmount = $totalAmount;
|
|
|
|
+
|
|
|
|
+ if ($useBalance && $totalAmount > 0) {
|
|
|
|
+ $wallet = $user->wallet;
|
|
|
|
+ abort_if(! $wallet, 404, '用户钱包不存在');
|
|
|
|
+
|
|
|
|
+ if ($wallet->available_balance >= $totalAmount) {
|
|
|
|
+ $balanceAmount = $totalAmount;
|
|
|
|
+ $payAmount = 0;
|
|
|
|
+ } else {
|
|
|
|
+ $balanceAmount = $wallet->available_balance;
|
|
|
|
+ $payAmount = bcsub($totalAmount, $balanceAmount, 2);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- $project->price = $agentProject->price;
|
|
|
|
- $project->duration = $agentProject->duration;
|
|
|
|
- $project->distance = $address->distance;
|
|
|
|
|
|
+ return [
|
|
|
|
+ 'total_amount' => $totalAmount,
|
|
|
|
+ 'balance_amount' => $balanceAmount,
|
|
|
|
+ 'pay_amount' => $payAmount,
|
|
|
|
+ 'coupon_amount' => $couponAmount,
|
|
|
|
+ 'project_amount' => $projectAmount,
|
|
|
|
+ 'delivery_fee' => $deliveryFee,
|
|
|
|
+ ];
|
|
|
|
+
|
|
|
|
+ } catch (Exception $e) {
|
|
|
|
+ Log::error(__CLASS__.'->'.__FUNCTION__.'计算订单金额失败:', [
|
|
|
|
+ 'message' => $e->getMessage(),
|
|
|
|
+ 'user_id' => $userId,
|
|
|
|
+ 'project_id' => $projectId,
|
|
|
|
+ 'trace' => $e->getTraceAsString(),
|
|
|
|
+ ]);
|
|
|
|
+ throw $e;
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
|
|
- // 计算金额
|
|
|
|
- $projectAmount = $project->price;
|
|
|
|
- $deliveryFee = $this->calculateDeliveryFee($coachId, $projectId, $agentId, $address?->distance);
|
|
|
|
- // $tipAmount = request()->has('order_id') ? Order::find(request()->input('order_id'))->tip_amount : 0;
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 获取项目价格
|
|
|
|
+ */
|
|
|
|
+ private function getProjectPrice($project, ?int $agentId, int $projectId): float
|
|
|
|
+ {
|
|
|
|
+ $price = $project->price;
|
|
|
|
|
|
|
|
+ if ($agentId) {
|
|
|
|
+ $agent = AgentInfo::where('state', 'enable')->find($agentId);
|
|
|
|
+ if ($agent) {
|
|
|
|
+ $agentProject = $agent->projects()
|
|
|
|
+ ->where('state', 'enable')
|
|
|
|
+ ->where('project_id', $projectId)
|
|
|
|
+ ->first();
|
|
|
|
+
|
|
|
|
+ if ($agentProject) {
|
|
|
|
+ $price = $agentProject->price;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return (float) $price;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 计算优惠券金额
|
|
|
|
+ */
|
|
|
|
+ private function calculateCouponAmount(): float
|
|
|
|
+ {
|
|
$couponAmount = 0;
|
|
$couponAmount = 0;
|
|
if (request()->has('coupon_id')) {
|
|
if (request()->has('coupon_id')) {
|
|
- // $coupon = Coupon::where('id', request()->input('coupon_id'))
|
|
|
|
- // ->where('state', 'enable')
|
|
|
|
- // ->firstOrFail();
|
|
|
|
- // $couponAmount = $coupon->amount;
|
|
|
|
|
|
+ // TODO: 优惠券逻辑
|
|
}
|
|
}
|
|
|
|
|
|
- $totalAmount = $projectAmount + $deliveryFee - $couponAmount;
|
|
|
|
|
|
+ return $couponAmount;
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 计算支付金额分配
|
|
|
|
+ */
|
|
|
|
+ private function calculatePaymentAmounts($user, float $totalAmount, bool $useBalance): array
|
|
|
|
+ {
|
|
$balanceAmount = 0;
|
|
$balanceAmount = 0;
|
|
$payAmount = $totalAmount;
|
|
$payAmount = $totalAmount;
|
|
|
|
|
|
if ($useBalance) {
|
|
if ($useBalance) {
|
|
$wallet = $user->wallet;
|
|
$wallet = $user->wallet;
|
|
- if ($wallet && $wallet->available_balance >= $totalAmount) {
|
|
|
|
|
|
+ if (! $wallet) {
|
|
|
|
+ throw new Exception('用户钱包不存在');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ($wallet->available_balance >= $totalAmount) {
|
|
$balanceAmount = $totalAmount;
|
|
$balanceAmount = $totalAmount;
|
|
$payAmount = 0;
|
|
$payAmount = 0;
|
|
- } elseif ($wallet) {
|
|
|
|
|
|
+ } else {
|
|
$balanceAmount = $wallet->available_balance;
|
|
$balanceAmount = $wallet->available_balance;
|
|
- $payAmount = $totalAmount - $balanceAmount;
|
|
|
|
|
|
+ $payAmount = bcsub($totalAmount, $balanceAmount, 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- return [
|
|
|
|
- 'total_amount' => $totalAmount,
|
|
|
|
- 'balance_amount' => $balanceAmount,
|
|
|
|
- 'pay_amount' => $payAmount,
|
|
|
|
- 'coupon_amount' => $couponAmount,
|
|
|
|
- // 'tip_amount' => $tipAmount,
|
|
|
|
- 'project_amount' => $projectAmount,
|
|
|
|
- 'delivery_fee' => $deliveryFee,
|
|
|
|
- ];
|
|
|
|
|
|
+ return [$balanceAmount, $payAmount];
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 指定技师
|
|
* 指定技师
|
|
*/
|
|
*/
|
|
- public function assignCoach($userId, $orderId, $coachId)
|
|
|
|
|
|
+ public function assignCoach(int $userId, int $orderId, int $coachId): bool
|
|
{
|
|
{
|
|
return DB::transaction(function () use ($userId, $orderId, $coachId) {
|
|
return DB::transaction(function () use ($userId, $orderId, $coachId) {
|
|
- // 参数校验
|
|
|
|
- $user = MemberUser::where('id', $userId)
|
|
|
|
- ->where('state', 'enable')
|
|
|
|
- ->firstOrFail();
|
|
|
|
-
|
|
|
|
- $order = Order::where('id', $orderId)
|
|
|
|
- ->where('user_id', $userId)
|
|
|
|
- ->whereIn('state', [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('state', 'free')
|
|
|
|
- // ->firstOrFail();
|
|
|
|
-
|
|
|
|
- // 修改订单
|
|
|
|
- $order->coach_id = $coachId;
|
|
|
|
- if ($order->state == 'created') {
|
|
|
|
- $amounts = $this->calculateOrderAmount($userId, $order->address_id, $coachId, $order->project_id, $order->agent_id, $order->payment_type == 'balance');
|
|
|
|
|
|
+ try {
|
|
|
|
+ // 参数校验
|
|
|
|
+ $user = MemberUser::where('id', $userId)
|
|
|
|
+ ->where('state', 'enable')
|
|
|
|
+ ->firstOrFail();
|
|
|
|
|
|
- $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'];
|
|
|
|
|
|
+ $order = Order::where('id', $orderId)
|
|
|
|
+ ->where('user_id', $userId)
|
|
|
|
+ ->whereIn('state', [0, 1, 6])
|
|
|
|
+ ->firstOrFail();
|
|
|
|
|
|
- if ($order->payment_type == 'balance') {
|
|
|
|
- $order->state = 'paid';
|
|
|
|
|
|
+ $coach = $this->validateCoach($coachId);
|
|
|
|
+
|
|
|
|
+ // 修改订单
|
|
|
|
+ $order->coach_id = $coachId;
|
|
|
|
+ if ($order->state == 'created') {
|
|
|
|
+ $amounts = $this->calculateOrderAmount(
|
|
|
|
+ $userId,
|
|
|
|
+ $order->address_id,
|
|
|
|
+ $coachId,
|
|
|
|
+ $order->project_id,
|
|
|
|
+ $order->agent_id,
|
|
|
|
+ $order->payment_type === 'balance'
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ $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->project_amount = $amounts->project_amount;
|
|
|
|
+ $order->delivery_fee = $amounts->delivery_fee;
|
|
|
|
+
|
|
|
|
+ if ($order->payment_type === 'balance') {
|
|
|
|
+ $order->state = 'paid';
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }
|
|
|
|
- if ($order->state == 'paid') {
|
|
|
|
- $order->state = 'assigned';
|
|
|
|
- }
|
|
|
|
- $order->save();
|
|
|
|
-
|
|
|
|
- // 创建订单历史
|
|
|
|
- OrderRecord::create([
|
|
|
|
- 'order_id' => $order->id,
|
|
|
|
- 'type' => 'assigned',
|
|
|
|
- 'user_id' => $userId,
|
|
|
|
- 'coach_id' => $coachId,
|
|
|
|
- ]);
|
|
|
|
|
|
+ if ($order->state == 'paid') {
|
|
|
|
+ $order->state = 'assigned';
|
|
|
|
+ }
|
|
|
|
+ $order->save();
|
|
|
|
|
|
- OrderRecord::create([
|
|
|
|
- 'order_id' => $order->id,
|
|
|
|
- 'type' => 'accepted',
|
|
|
|
- 'user_id' => $userId,
|
|
|
|
- 'coach_id' => $coachId,
|
|
|
|
- 'remark' => '抢单成功',
|
|
|
|
- ]);
|
|
|
|
|
|
+ // 创建订单历史
|
|
|
|
+ OrderRecord::create([
|
|
|
|
+ 'order_id' => $order->id,
|
|
|
|
+ 'type' => 'assigned',
|
|
|
|
+ 'user_id' => $userId,
|
|
|
|
+ 'coach_id' => $coachId,
|
|
|
|
+ ]);
|
|
|
|
|
|
- // 更新抢单池
|
|
|
|
- OrderGrabRecord::where('order_id', $orderId)
|
|
|
|
- ->update(['state' => 'success', 'coach_id' => $coachId]);
|
|
|
|
|
|
+ OrderRecord::create([
|
|
|
|
+ 'order_id' => $order->id,
|
|
|
|
+ 'type' => 'accepted',
|
|
|
|
+ 'user_id' => $userId,
|
|
|
|
+ 'coach_id' => $coachId,
|
|
|
|
+ 'remark' => '抢单成功',
|
|
|
|
+ ]);
|
|
|
|
|
|
- // 更新排班
|
|
|
|
- // $schedule->state = 'busy';
|
|
|
|
- // $schedule->save();
|
|
|
|
|
|
+ // 更新抢单池
|
|
|
|
+ OrderGrabRecord::where('order_id', $orderId)
|
|
|
|
+ ->update(['state' => 'success', 'coach_id' => $coachId]);
|
|
|
|
|
|
- return true;
|
|
|
|
|
|
+ return true;
|
|
|
|
+ } catch (Exception $e) {
|
|
|
|
+ Log::error('分配技师失败:', [
|
|
|
|
+ 'message' => $e->getMessage(),
|
|
|
|
+ 'user_id' => $userId,
|
|
|
|
+ 'order_id' => $orderId,
|
|
|
|
+ 'coach_id' => $coachId,
|
|
|
|
+ ]);
|
|
|
|
+ throw $e;
|
|
|
|
+ }
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|