|
@@ -2,25 +2,25 @@
|
|
|
|
|
|
namespace App\Services\Coach;
|
|
|
|
|
|
-use App\Enums\OrderGrabRecordStatus;
|
|
|
-use App\Enums\OrderRecordStatus;
|
|
|
-use App\Enums\OrderStatus;
|
|
|
+use App\Models\Order;
|
|
|
use App\Enums\OrderType;
|
|
|
-use App\Enums\ProjectStatus;
|
|
|
-use App\Enums\TechnicianAuthStatus;
|
|
|
-use App\Enums\TechnicianLocationType;
|
|
|
-use App\Enums\TechnicianStatus;
|
|
|
-use App\Jobs\AutoFinishOrder;
|
|
|
use App\Models\CoachUser;
|
|
|
+use App\Enums\OrderStatus;
|
|
|
use App\Models\MemberUser;
|
|
|
-use App\Models\Order;
|
|
|
-use App\Models\OrderGrabRecord;
|
|
|
use App\Models\OrderRecord;
|
|
|
+use App\Enums\ProjectStatus;
|
|
|
use App\Models\SettingGroup;
|
|
|
-use App\Services\SettingItemService;
|
|
|
-use Illuminate\Support\Facades\Cache;
|
|
|
+use App\Jobs\AutoFinishOrder;
|
|
|
+use App\Enums\TechnicianStatus;
|
|
|
+use App\Models\OrderGrabRecord;
|
|
|
+use App\Enums\OrderRecordStatus;
|
|
|
use Illuminate\Support\Facades\DB;
|
|
|
+use App\Enums\TechnicianAuthStatus;
|
|
|
use Illuminate\Support\Facades\Log;
|
|
|
+use App\Enums\OrderGrabRecordStatus;
|
|
|
+use App\Services\SettingItemService;
|
|
|
+use App\Enums\TechnicianLocationType;
|
|
|
+use Illuminate\Support\Facades\Cache;
|
|
|
use Illuminate\Support\Facades\Redis;
|
|
|
|
|
|
class OrderService
|
|
@@ -83,7 +83,6 @@ class OrderService
|
|
|
'items' => $items,
|
|
|
'total' => $paginator->total(),
|
|
|
];
|
|
|
-
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('获取技师订单列表失败', [
|
|
|
'user_id' => $userId,
|
|
@@ -141,7 +140,6 @@ class OrderService
|
|
|
'page',
|
|
|
$params['page'] ?? 1
|
|
|
);
|
|
|
-
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('获取可抢订单列表失败', [
|
|
|
'user_id' => $userId,
|
|
@@ -159,9 +157,9 @@ class OrderService
|
|
|
private function validateCoach(MemberUser $user): array
|
|
|
{
|
|
|
$coach = $user->coach;
|
|
|
- abort_if(! $coach, 404, '技师��存在');
|
|
|
+ abort_if(! $coach, 404, '技师不存在');
|
|
|
abort_if(! $coach->info, 404, '技师信息不存在');
|
|
|
- abort_if($coach->info->state != TechnicianStatus::ACTIVE->value, 404, '技师状异常');
|
|
|
+ abort_if($coach->info->state != TechnicianStatus::ACTIVE->value, 404, '技师状态异常');
|
|
|
abort_if($coach->real->state != TechnicianAuthStatus::PASSED->value, 404, '技师实名认证未通过');
|
|
|
abort_if($coach->qual->state != TechnicianAuthStatus::PASSED->value, 404, '技师资质认证未通过');
|
|
|
|
|
@@ -321,7 +319,7 @@ class OrderService
|
|
|
|
|
|
$order->project->traffic_fee = round($trafficFee, 2);
|
|
|
|
|
|
- // ��程收费
|
|
|
+ // 程收费
|
|
|
if ($coachProject->is_round_trip) {
|
|
|
$order->project->traffic_fee *= 2;
|
|
|
}
|
|
@@ -361,7 +359,7 @@ class OrderService
|
|
|
// 验证订单状态
|
|
|
abort_if($order->state !== OrderStatus::CREATED->value, 400, '订单状态异常,无法抢单');
|
|
|
|
|
|
- // 验���订单类型
|
|
|
+ // 验证订单类型
|
|
|
abort_if($order->type !== OrderType::GRAB->value, 400, '该订单不是抢单类型');
|
|
|
|
|
|
// 检查技师是否已参与抢单
|
|
@@ -374,8 +372,8 @@ class OrderService
|
|
|
// 通过Redis GEO计算订单与技师的距离
|
|
|
$distance = Redis::geodist(
|
|
|
'order_locations',
|
|
|
- 'order:'.$order->id,
|
|
|
- $location->longitude.','.$location->latitude,
|
|
|
+ 'order:' . $order->id,
|
|
|
+ $location->longitude . ',' . $location->latitude,
|
|
|
'km'
|
|
|
) ?? PHP_FLOAT_MAX;
|
|
|
abort_if($distance > self::MAX_DISTANCE, 400, '订单超出服务范围');
|
|
@@ -407,7 +405,6 @@ class OrderService
|
|
|
'message' => '已参与抢单',
|
|
|
'order_id' => $orderId,
|
|
|
];
|
|
|
-
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('技师参与抢单失败', [
|
|
|
'user_id' => $userId,
|
|
@@ -466,11 +463,10 @@ class OrderService
|
|
|
]);
|
|
|
|
|
|
return [
|
|
|
- 'message' => '��单成功',
|
|
|
+ 'message' => '接单成功',
|
|
|
'order_id' => $orderId,
|
|
|
'order_no' => $order->order_no,
|
|
|
];
|
|
|
-
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('技师接单失败', [
|
|
|
'user_id' => $userId,
|
|
@@ -567,7 +563,6 @@ class OrderService
|
|
|
'reject_count' => $rejectCount + 1,
|
|
|
'max_reject_count' => 5,
|
|
|
];
|
|
|
-
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('技师拒单失败', [
|
|
|
'user_id' => $userId,
|
|
@@ -697,7 +692,7 @@ class OrderService
|
|
|
'coach_locations',
|
|
|
$order->longitude,
|
|
|
$order->latitude,
|
|
|
- $coach->id.'_'.TechnicianLocationType::CURRENT->value
|
|
|
+ $coach->id . '_' . TechnicianLocationType::CURRENT->value
|
|
|
);
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('更新技师位置失败', [
|
|
@@ -775,7 +770,7 @@ class OrderService
|
|
|
$now = now();
|
|
|
|
|
|
// 更新订单状态为服务中
|
|
|
- $order->state = OrderStatus::SERVING->value;
|
|
|
+ $order->state = OrderStatus::SERVICING->value;
|
|
|
$order->save();
|
|
|
|
|
|
// 记录订单状态变更日志
|
|
@@ -812,7 +807,6 @@ class OrderService
|
|
|
'service_start_time' => $now,
|
|
|
],
|
|
|
];
|
|
|
-
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('开始服务失败', [
|
|
|
'user_id' => $userId,
|
|
@@ -852,7 +846,7 @@ class OrderService
|
|
|
abort_if($now - $qrTimestamp > 300, 400, '二维码已过期');
|
|
|
|
|
|
// 验证签名
|
|
|
- $correctSign = md5("order_{$order->id}_{$timestamp}_".config('app.key'));
|
|
|
+ $correctSign = md5("order_{$order->id}_{$timestamp}_" . config('app.key'));
|
|
|
abort_if($sign !== $correctSign, 400, '二维码签名错误');
|
|
|
}
|
|
|
|
|
@@ -914,7 +908,6 @@ class OrderService
|
|
|
'leave_time' => now(),
|
|
|
],
|
|
|
];
|
|
|
-
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('技师撤离失败', [
|
|
|
'user_id' => $userId,
|
|
@@ -975,7 +968,7 @@ class OrderService
|
|
|
try {
|
|
|
Redis::zrem(
|
|
|
'coach_locations',
|
|
|
- $coach->id.'_'.TechnicianLocationType::CURRENT->value
|
|
|
+ $coach->id . '_' . TechnicianLocationType::CURRENT->value
|
|
|
);
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('删除技师位置失败', [
|
|
@@ -1044,7 +1037,7 @@ class OrderService
|
|
|
// 检查服务距离是否存在,并且是否大于0
|
|
|
if (isset($data['distance']) && $data['distance'] > 0) {
|
|
|
// 从全局配置中验证服务距离的合理范围
|
|
|
- abort_if($data['distance'] > $distanceSettingItem->max_value, 422, '服务距离不能超过'.$distanceSettingItem->max_value.'公里');
|
|
|
+ abort_if($data['distance'] > $distanceSettingItem->max_value, 422, '服务距离不能超过' . $distanceSettingItem->max_value . '公里');
|
|
|
|
|
|
// 更新技师服务距离配置
|
|
|
$coach->settingValues()->updateOrCreate(
|
|
@@ -1066,7 +1059,6 @@ class OrderService
|
|
|
'coach_id' => $coach->id,
|
|
|
'settings' => $data,
|
|
|
];
|
|
|
-
|
|
|
} catch (\Exception $e) {
|
|
|
Log::error('订单设置更新失败', [
|
|
|
'user_id' => $userId,
|
|
@@ -1079,4 +1071,43 @@ class OrderService
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取订单设置
|
|
|
+ *
|
|
|
+ * 业务流程:
|
|
|
+ * 1. 获取技师的订单设置
|
|
|
+ * 2. 获取系统配置的限制值
|
|
|
+ * 3. 返回设置信息
|
|
|
+ *
|
|
|
+ * @param CoachUser $coach 技师对象
|
|
|
+ * @return array 返回设置信息,包含:
|
|
|
+ * - distance: float 当前服务距离
|
|
|
+ * - distance_max: float 最大服务距离
|
|
|
+ * - distance_min: float 最小服务距离
|
|
|
+ */
|
|
|
+ public function getOrderSettings(CoachUser $coach): array
|
|
|
+ {
|
|
|
+ // 获取订单配置分组
|
|
|
+ $settingGroup = SettingGroup::where('code', 'order')->first();
|
|
|
+ abort_if(!$settingGroup, 404, '订单配置分组不存在');
|
|
|
+
|
|
|
+ // 获取距离配置项
|
|
|
+ $distanceSettingItem = $settingGroup->items()
|
|
|
+ ->where('code', 'distance')
|
|
|
+ ->first();
|
|
|
+ abort_if(!$distanceSettingItem, 404, '距离配置项不存在');
|
|
|
+
|
|
|
+ // 获取技师的距离设置
|
|
|
+ $distanceSetting = $coach->settingValues()
|
|
|
+ ->where('item_id', $distanceSettingItem->id)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ // 返回设置信息
|
|
|
+ return [
|
|
|
+ 'distance' => (float)($distanceSetting?->value ?? $distanceSettingItem->default_value), // 当前服务距离
|
|
|
+ 'distance_max' => (float)$distanceSettingItem->max_value, // 最大服务距离限制
|
|
|
+ 'distance_min' => (float)$distanceSettingItem->min_value, // 最小服务距离限制
|
|
|
+ ];
|
|
|
+ }
|
|
|
}
|