|
@@ -513,12 +513,31 @@ readonly class OrderService
|
|
|
// 提取方法:验证技师
|
|
|
public function validateCoach(int $coachId): CoachUser
|
|
|
{
|
|
|
- return CoachUser::where('id', $coachId)
|
|
|
- ->where('state', TechnicianStatus::ACTIVE->value)
|
|
|
- ->whereHas('info', fn ($q) => $q->where('state', TechnicianAuthStatus::PASSED->value))
|
|
|
- ->whereHas('qual', fn ($q) => $q->where('state', TechnicianAuthStatus::PASSED->value))
|
|
|
- ->whereHas('real', fn ($q) => $q->where('state', TechnicianAuthStatus::PASSED->value))
|
|
|
- ->firstOrFail();
|
|
|
+ // 查询技师基本信息
|
|
|
+ $coach = CoachUser::query()
|
|
|
+ ->with(['info', 'qual', 'real'])
|
|
|
+ ->where('id', $coachId)
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ // 验证技师是否存在
|
|
|
+ abort_if(! $coach, 400, '技师不存在');
|
|
|
+
|
|
|
+ // 验证技师状态
|
|
|
+ abort_if($coach->state !== TechnicianStatus::ACTIVE->value, 400, '技师未激活');
|
|
|
+
|
|
|
+ // 验证基本信息认证
|
|
|
+ abort_if(! $coach->info || $coach->info->state !== TechnicianAuthStatus::PASSED->value,
|
|
|
+ 400, '技师基本信息未认证');
|
|
|
+
|
|
|
+ // 验证资质认证
|
|
|
+ abort_if(! $coach->qual || $coach->qual->state !== TechnicianAuthStatus::PASSED->value,
|
|
|
+ 400, '技师资质未认证');
|
|
|
+
|
|
|
+ // 验证实名认证
|
|
|
+ abort_if(! $coach->real || $coach->real->state !== TechnicianAuthStatus::PASSED->value,
|
|
|
+ 400, '技师实名未认证');
|
|
|
+
|
|
|
+ return $coach;
|
|
|
}
|
|
|
|
|
|
// 提取方法:获取原始订单
|
|
@@ -1845,48 +1864,52 @@ readonly class OrderService
|
|
|
*/
|
|
|
private function calculateDistance(int $coachId, int $addressId, float $lat, float $lng): float
|
|
|
{
|
|
|
- // 如果提供了地址ID,优先使用地址表中的经纬度
|
|
|
- if ($addressId > 0) {
|
|
|
- // 查询地址信息
|
|
|
- $address = MemberAddress::find($addressId);
|
|
|
- // 使用地址的经纬度,如果没有则使用传入的经纬度
|
|
|
- $lat = $address?->latitude ?? $lat;
|
|
|
- $lng = $address?->longitude ?? $lng;
|
|
|
- }
|
|
|
+ try {
|
|
|
+ // 如果提供了地址ID,优先使用地址表中的经纬度
|
|
|
+ if ($addressId > 0) {
|
|
|
+ $address = MemberAddress::find($addressId);
|
|
|
+ // 使用地址的经纬度,如果没有则使用传入的经纬度
|
|
|
+ $lat = $address?->latitude ?? $lat;
|
|
|
+ $lng = $address?->longitude ?? $lng;
|
|
|
+ }
|
|
|
|
|
|
- // 从Redis获取技师的两个位置点信息
|
|
|
- // 获取常用地址位置(如家庭地址)
|
|
|
- $homeLocation = Redis::geopos(
|
|
|
- 'coach_locations',
|
|
|
- $coachId.'_'.TechnicianLocationType::COMMON->value
|
|
|
- );
|
|
|
- // 获取当前实时位置
|
|
|
- $workLocation = Redis::geopos(
|
|
|
- 'coach_locations',
|
|
|
- $coachId.'_'.TechnicianLocationType::CURRENT->value
|
|
|
- );
|
|
|
+ // 从Redis获取技师的两个位置点信息
|
|
|
+ // 获取常用地址位置(如家庭地址)
|
|
|
+ $homeLocation = Redis::geopos(
|
|
|
+ 'coach_locations',
|
|
|
+ $coachId.'_'.TechnicianLocationType::COMMON->value
|
|
|
+ );
|
|
|
+ // 获取当前实时位置
|
|
|
+ $workLocation = Redis::geopos(
|
|
|
+ 'coach_locations',
|
|
|
+ $coachId.'_'.TechnicianLocationType::CURRENT->value
|
|
|
+ );
|
|
|
|
|
|
- // 初始化最近距离变量
|
|
|
- $nearestDistance = null;
|
|
|
-
|
|
|
- // 分别计算与两个位置点的距离
|
|
|
- // 计算与常用地址的距离
|
|
|
- $homeDistance = $homeLocation && $homeLocation[0] ?
|
|
|
- $this->getDistance($homeLocation[0][1], $homeLocation[0][0], $lat, $lng) :
|
|
|
- null;
|
|
|
- // 计算与当前位置的距离
|
|
|
- $workDistance = $workLocation && $workLocation[0] ?
|
|
|
- $this->getDistance($workLocation[0][1], $workLocation[0][0], $lat, $lng) :
|
|
|
- null;
|
|
|
-
|
|
|
- // 选择最近的距离作为服务距离
|
|
|
- if ($homeDistance < $workDistance) {
|
|
|
- $nearestDistance = $homeDistance;
|
|
|
- } else {
|
|
|
- $nearestDistance = $workDistance;
|
|
|
- }
|
|
|
+ $distances = [];
|
|
|
+
|
|
|
+ // 计算与常用地址的距离
|
|
|
+ if ($homeLocation && $homeLocation[0]) {
|
|
|
+ $distances[] = $this->getDistance($homeLocation[0][1], $homeLocation[0][0], $lat, $lng);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算与当前位置的距离
|
|
|
+ if ($workLocation && $workLocation[0]) {
|
|
|
+ $distances[] = $this->getDistance($workLocation[0][1], $workLocation[0][0], $lat, $lng);
|
|
|
+ }
|
|
|
|
|
|
- return $nearestDistance;
|
|
|
+ // 如果有有效距离,返回最小值;否则返回0
|
|
|
+ return !empty($distances) ? min($distances) : 0.0;
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error('计算距离失败', [
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
+ 'coach_id' => $coachId,
|
|
|
+ 'address_id' => $addressId,
|
|
|
+ 'lat' => $lat,
|
|
|
+ 'lng' => $lng,
|
|
|
+ ]);
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|