|
@@ -255,16 +255,16 @@ readonly class OrderService
|
|
|
);
|
|
|
|
|
|
// 加钟订单使用原订单地址和技师ID
|
|
|
- if (!empty($data['order_id'])) {
|
|
|
+ if (! empty($data['order_id'])) {
|
|
|
$order = Order::findOrFail($data['order_id']);
|
|
|
|
|
|
// 验证订单状态
|
|
|
abort_if(
|
|
|
- !in_array($order->state, [
|
|
|
+ ! in_array($order->state, [
|
|
|
OrderStatus::PAID->value,
|
|
|
OrderStatus::ACCEPTED->value,
|
|
|
- OrderStatus::SERVICE->value,
|
|
|
- OrderStatus::SERVICE_ING->value,
|
|
|
+ OrderStatus::STARTED->value,
|
|
|
+ OrderStatus::SERVING->value,
|
|
|
]),
|
|
|
422,
|
|
|
'原订单状态不允许加钟'
|
|
@@ -278,7 +278,8 @@ readonly class OrderService
|
|
|
// 3. 获取地址
|
|
|
$address = MemberUser::find($userId)->addresses()
|
|
|
->where('id', $data['address_id'])
|
|
|
- ->firstOrFail();
|
|
|
+ ->first();
|
|
|
+ abort_if(! $address, 404, '收货地址不存在');
|
|
|
|
|
|
// 3. 创建订单
|
|
|
$order = $this->createOrderData(['user_id' => $userId, ...$data], $amounts, $address);
|
|
@@ -332,12 +333,14 @@ readonly class OrderService
|
|
|
// 验证用户状态
|
|
|
$user = MemberUser::where('id', $userId)
|
|
|
->where('state', UserStatus::OPEN->value)
|
|
|
- ->firstOrFail();
|
|
|
+ ->first();
|
|
|
+ abort_if(! $user, 404, '用户不存在');
|
|
|
+ abort_if($user->state != UserStatus::OPEN->value, 403, '用户状态异常');
|
|
|
|
|
|
// 验证项目状态
|
|
|
- $project = Project::where('id', $data['project_id'])
|
|
|
- ->where('state', ProjectStatus::OPEN->value)
|
|
|
- ->firstOrFail();
|
|
|
+ $project = Project::where('id', $data['project_id'])->first();
|
|
|
+ abort_if(! $project, 404, '服务项目不存在');
|
|
|
+ abort_if($project->state != ProjectStatus::OPEN->value, 403, '服务项目未开放');
|
|
|
|
|
|
// 验证服务时间和技师状态
|
|
|
if (! empty($data['service_time']) && ! empty($data['coach_id'])) {
|
|
@@ -403,29 +406,27 @@ readonly class OrderService
|
|
|
*/
|
|
|
private function processBalancePayment(Order $order): void
|
|
|
{
|
|
|
- $wallet = $order->user->wallet;
|
|
|
-
|
|
|
- // 检查钱包可用余额是否足够
|
|
|
- abort_if($wallet->available_balance < $order->balance_amount, 400, '钱包可用余额不足,无法完成支付');
|
|
|
-
|
|
|
- // 扣减钱包余额
|
|
|
- $wallet->decrement('total_balance', $order->balance_amount);
|
|
|
- $wallet->decrement('available_balance', $order->balance_amount);
|
|
|
+ $user = MemberUser::find($order->user_id);
|
|
|
+ abort_if(! $user, 404, sprintf('用户[%d]不存在', $order->user_id));
|
|
|
|
|
|
- // 增加冻结金额
|
|
|
- $wallet->increment('frozen_amount', $order->balance_amount);
|
|
|
+ $wallet = $user->wallet;
|
|
|
+ abort_if($wallet->available_balance < $order->balance_amount, 400,
|
|
|
+ sprintf('用户[%d]可用余额[%.2f]不足,需要[%.2f]',
|
|
|
+ $user->id,
|
|
|
+ $wallet->available_balance,
|
|
|
+ $order->balance_amount
|
|
|
+ ));
|
|
|
|
|
|
- // 创建钱包交易记录
|
|
|
- $wallet->transRecords()->create([
|
|
|
- 'amount' => -$order->balance_amount,
|
|
|
- 'trans_type' => TransactionType::PAYMENT->value,
|
|
|
- 'owner_type' => Order::class,
|
|
|
- 'owner_id' => $order->id,
|
|
|
- 'remark' => '订单支付',
|
|
|
- 'before_balance' => $wallet->total_balance + $order->balance_amount,
|
|
|
- 'after_balance' => $wallet->total_balance,
|
|
|
- 'state' => 'success',
|
|
|
- ]);
|
|
|
+ // 扣除余额
|
|
|
+ if ($order->balance_amount > 0) {
|
|
|
+ $this->walletService->deduct(
|
|
|
+ userId: $user->id,
|
|
|
+ amount: $order->balance_amount,
|
|
|
+ type: TransactionType::ORDER_PAYMENT,
|
|
|
+ objectId: $order->id,
|
|
|
+ remark: sprintf('订单[%s]余额支付', $order->order_no)
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -450,14 +451,9 @@ readonly class OrderService
|
|
|
*/
|
|
|
private function notifyOrderCreated(Order $order): void
|
|
|
{
|
|
|
- // TODO: 实现订单创建通������
|
|
|
+ // TODO: 实现订单创建通知
|
|
|
// 1. 通知用户
|
|
|
// event(new OrderCreatedEvent($order));
|
|
|
-
|
|
|
- // 2. 通知技师(如果有)
|
|
|
- if ($order->coach_id) {
|
|
|
- // event(new OrderAssignedToCoachEvent($order));
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -947,7 +943,7 @@ readonly class OrderService
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 分页获取订单列表
|
|
|
+ * 分页获取订���列表
|
|
|
*/
|
|
|
private function paginateOrderList($query, array $filters)
|
|
|
{
|
|
@@ -969,7 +965,7 @@ readonly class OrderService
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * �������化订��列表项
|
|
|
+ * 格式化订单列表项
|
|
|
*/
|
|
|
private function formatOrderListItem(Order $order): array
|
|
|
{
|
|
@@ -1256,7 +1252,7 @@ readonly class OrderService
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- // 计算实际可��金额(总金额减去违约金)
|
|
|
+ // 计算实际可退金额(总金额减去违约金)
|
|
|
$totalRefund = bcsub($order->total_amount, $deductAmount, 2);
|
|
|
|
|
|
// 优先退还用户使用的余额部分
|
|
@@ -1434,7 +1430,7 @@ readonly class OrderService
|
|
|
// 2. 获取计费规则
|
|
|
$feeRules = $this->getDeliveryFeeRules($coachId, $agentId);
|
|
|
|
|
|
- // 3. 计算路费
|
|
|
+ // 3. ��算路费
|
|
|
return $this->calculateFeeByRules($distance, $feeRules);
|
|
|
|
|
|
} catch (Exception $e) {
|
|
@@ -1576,7 +1572,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, // 最大路费(元)
|
|
@@ -1686,7 +1682,7 @@ readonly class OrderService
|
|
|
// 1. 验证用户状态和权限
|
|
|
$user = $this->validateUserForCalculation($userId);
|
|
|
|
|
|
- // 2. 获取项目信息和价格(包含代理���价格)
|
|
|
+ // 2. 获取项目信息和价格(包含代理价格)
|
|
|
$project = $this->getProjectWithPrice($projectId, $agentId);
|
|
|
|
|
|
// 3. 计算路费(如果有技师)
|
|
@@ -1760,7 +1756,7 @@ readonly class OrderService
|
|
|
->where('state', ProjectStatus::OPEN->value)
|
|
|
->first();
|
|
|
|
|
|
- abort_if(! $project, 404, '项目不���在或���态异常');
|
|
|
+ abort_if(! $project, 404, '项目不存在或状态异常');
|
|
|
|
|
|
// 如果有代理商,获取代理商价格
|
|
|
if ($agentId) {
|
|
@@ -1953,11 +1949,11 @@ readonly class OrderService
|
|
|
{
|
|
|
|
|
|
try {
|
|
|
- // 查询��单信息
|
|
|
+ // 查询订单信息
|
|
|
$order = Order::where('id', $orderId)
|
|
|
->whereIn('state', [OrderStatus::CREATED->value])
|
|
|
->firstOrFail();
|
|
|
- // 查询抢单池列表
|
|
|
+ // 查询抢单池���表
|
|
|
$grabList = $order->grabRecords()->with(['coach.info'])->get();
|
|
|
|
|
|
// 格式化返回数据
|
|
@@ -2108,7 +2104,7 @@ readonly class OrderService
|
|
|
// 验证余额
|
|
|
$user = MemberUser::find($userId);
|
|
|
$wallet = $user->wallet;
|
|
|
- abort_if($wallet->available_balance < $order->balance_amount, 400, '可���余额不足');
|
|
|
+ abort_if($wallet->available_balance < $order->balance_amount, 400, '可用余额不足');
|
|
|
|
|
|
// 扣除余额
|
|
|
DB::transaction(function () use ($wallet, $order, $userId, $coachId) {
|
|
@@ -2560,4 +2556,33 @@ readonly class OrderService
|
|
|
|
|
|
return $coach;
|
|
|
}
|
|
|
+
|
|
|
+ public function getOrder(int $orderId): Order
|
|
|
+ {
|
|
|
+ $order = Order::find($orderId);
|
|
|
+ abort_if(! $order, 404, '订单不存在');
|
|
|
+
|
|
|
+ return $order;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function findOrder(int $orderId): Order
|
|
|
+ {
|
|
|
+ $order = Order::find($orderId);
|
|
|
+ abort_if(! $order, 404, sprintf('订单[%d]不存在', $orderId));
|
|
|
+
|
|
|
+ return $order;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function getOrderForPayment(int $orderId): Order
|
|
|
+ {
|
|
|
+ $order = Order::where('id', $orderId)
|
|
|
+ ->whereIn('state', [OrderStatus::CREATED->value])
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ abort_if(! $order, 404, sprintf('订单[%d]不存在', $orderId));
|
|
|
+ abort_if($order->state !== OrderStatus::CREATED->value, 422,
|
|
|
+ sprintf('订单[%d]状态为[%s],不允许支付', $orderId, $order->state));
|
|
|
+
|
|
|
+ return $order;
|
|
|
+ }
|
|
|
}
|