'平台已接单', 20 => '司机已结单', 30 => '正在服务中', 40 => '已完成', 50 => '已取消' ]; public function searchOrderNoAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->where('order_no', $value); } public function searchUserIdAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->where('user_id', $value); } public function searchDriverIdAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->where('driver_id', $value); } public function searchStatusAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->where('status', $value); } public function searchStatusInAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->whereIn('status', $value); } public function searchTypeInAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->whereIn('type', $value); } public function searchDriverStatusAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->whereIn('driver_status', $value); } public function searchAppointmentTimeNotAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->where('appointment_time', '>', 0); } public function searchAppointmentTimeZeroAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->where('appointment_time', 0); } public function searchAppointmentTimeBetweenAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->whereBetween('appointment_time', $value); } public function searchAppointmentTimeGtAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->where('appointment_time','>=', $value); } public function searchPushStatusAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->where('push_status', $value); } public function searchPushStatusInAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->whereIn('push_status', $value); } public function searchStatDistanceAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->havingRaw('(stat_distance < ? and appointment_time = 0) or appointment_time != 0', [$value]); } public function searchStatusOrderByAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } $order = implode(',',$value); return $query->orderByRaw("FIELD(status,{$order})"); } public function searchEndDriverDateBetweenAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->whereBetween('end_driver_time', $value); } // 筛选,如果是快车和接送机 则需要判断司机车型是否大于 订单所需车型 public function searchDriverCarSeatIdAttribute($query, $value, array $params): mixed { if (empty($value)) { return $query; } return $query->where(function ($where) use ($value){ $where->whereIn('type',[10,20])->where('car_seat_id','<=', $value); }); } public function createOrder(int $user_id, array $params = [], array $point = []) { $params['user_id'] = $user_id; $params['order_no'] = Common::createOrderNo('C'); $params['status'] = 10; $params['create_time'] = time(); if (!$order_id = self::query()->insertGetId($params)) { return $this->error('订单创建失败'); } $pointNum = count($point); // 机场坐标 $common_airport_coord = array_values(site('common_airport_coord')); // 接送机范围 $common_airport_range = site('common_airport_range'); // 市区邮编 $common_city_postal_code = array_values(site('common_city_postal_code')); // 创建途径点 foreach ($point as $key => $item) { if ($key == 0) { $type = 1; } elseif ($key == ($pointNum - 1)) { $type = 2; } else { $type = 3; } $is_in_city = 0;// 是否在市区:1=是,0=否 $is_at_airport = 0;// 是否在机场:1=是,0=否 // 判断 起始点 途径点 是否 在市区 if (in_array($item['postal_code'], $common_city_postal_code)) { $is_in_city = 1; } // 循环判断 起始点 途径点 是否 在机场附近 foreach ($common_airport_coord as $coord) { [$lng, $lat] = explode(',', $coord); [$cha_km,$unit] = Common::distance((float)$lng, (float)$lat, (float)$item['lng'], (float)$item['lat'], 1); if ($cha_km <= $common_airport_range) { $is_at_airport = 1; } } $order_point[] = [ 'user_id' => $user_id, 'order_id' => $order_id, 'order_no' => $params['order_no'], 'type' => $type, 'name' => $item['name'] ?? '', 'phone' => $item['phone'] ?? '', 'lng' => $item['lng'], 'lat' => $item['lat'], 'address' => $item['address'], 'postal_code' => $item['postal_code'], 'is_in_city' => $is_in_city, 'is_at_airport' => $is_at_airport, 'status' => 1, 'create_time' => time() ]; } if (isset($order_point)) { if (!OrderPointModel::query()->insert($order_point)) { return $this->error('创建途径点失败'); } } return $this->success('提交订单成功', [ 'order_no' => $params['order_no'] ]); } /** * 取消订单 * @param string $order_no * @return bool */ public function cancel(string $order_no,int $user_id = 0,int $driver_id = 0,string $reason = '',int $is_system = 0) { $params['order_no'] = $order_no; if (!empty($user_id)){ $params['user_id'] = $user_id; } if (!empty($driver_id)){ $params['driver_id'] = $driver_id; } $order = $this->getDetail(params: $params, with: ['user']); if ((!empty($params['user_id']) && !in_array($order['status'],[10,20,30])) || (!empty($params['driver_id']) && $order['status'] != 20)){ $status_name = self::status[$order['status']]; return $this->error("当前订单{$status_name},无法取消"); } if (!empty($params['user_id']) && $order['status'] == 30 && $order['driver_status'] != 1){ return $this->error("订单只能在司机到达出发点前才可取消"); } // 如果用户编号和司机编号都没传 则只有司机未结单的状态才可取消 if (empty($params['user_id']) && empty($params['driver_id']) && $is_system === 0 && !in_array($order['status'],[10])){ $status_name = self::status[$order['status']]; return $this->error("当前订单{$status_name},无法取消"); } // 订单取消原因 if (!empty($driver_id)){ $reason = "司机已取消订单:{$params['order_no']}"; // 发送系统消息 MessageModel::add([ 'user_id' => $order['user_id'], 'type' => 1, 'name' => "订单已取消", 'content' => $reason, 'value' => $order_no ]); if ($order['user']['area_code'] == '+86') { $sms = new AliSms(); if (!$sms->send($order['user']['mobile'], [],4)) { return $this->error($sms->getMessage() ?? '发送失败'); } } else { // 国外短信 $text = "【好滴用车】您的好滴用车订单已被司机取消,请前往好滴用车用户端重新下单"; $sms = new Sms(); if (!$sms->send("{$order['user']['area_code']}{$order['user']['mobile']}", $text)) { return $this->error($sms->getMessage() ?? '发送失败'); } } }else{ if (!empty($order['driver_id'])){ $reason = "用户已取消订单:{$params['order_no']},{$reason}"; // 发送系统消息 DriverMessageModel::add([ 'driver_id' => $order['driver_id'], 'type' => 1, 'name' => "订单已取消", 'content' => $reason, 'value' => $order_no ]); }elseif ($is_system === 1){ $reason = "系统操作:{$params['order_no']},{$reason}"; // 发送系统消息 MessageModel::add([ 'user_id' => $order['user_id'], 'type' => 1, 'name' => "订单已取消", 'content' => $reason, 'value' => $order_no ]); }else{ $reason = "订单超时暂无司机接单:{$params['order_no']},{$reason}"; // 发送系统消息 MessageModel::add([ 'user_id' => $order['user_id'], 'type' => 1, 'name' => "订单已取消", 'content' => $reason, 'value' => $order_no ]); } } $orderUp = OrderModel::query()->where('id', $order['id'])->whereIn('status',[10, 20, 30])->update([ 'status' => 50, 'cancel_reason' => $reason, 'update_time' => time() ]); if (!$orderUp) { return $this->error('操作失败'); } // 在线支付需要退还支付金额 if ($order['pay_type'] == 1){ $type_name = DriverTypeBusiness::type[$order['type']] ?? ''; $wallet = new UserWalletModel(); if (!$wallet->change($order['user_id'],(float)$order['pay_amount'],"{$type_name}订单取消退还支付金额",4)){ return $this->error($wallet->getMessage()); } } // 退还优惠券 if (!empty($order['coupon_id'])){ if (!UserCouponModel::query()->where('id',$order['coupon_id'])->update(['is_use'=>0,'update_time'=>time()])){ return $this->error('优惠券退还失败'); } } // 删除司机用户聊天框 RedisUtil::getInstance(RedisKeyEnum::USER_DRIVER_CHAT_DEL,"user_{$order['user_id']}")->setex("driver_{$order['driver_id']}",500); $tencent = new TencentIm(); $tencent->delete_chat("user_{$order['user_id']}","driver_{$order['driver_id']}"); return $this->success('操作成功'); } /** * 邀请司机接单 * @param int $order_id * @return bool */ public function tailwind_invite(int $order_id, int $driver_order_id) { $orderUp = OrderModel::query()->where('id', $order_id)->where('status', 10)->update([ 'driver_order_id' => $driver_order_id, 'update_time' => time() ]); if (!$orderUp) { return $this->error('操作失败'); } return $this->success('操作成功'); } /** * 加价 * @param int $order_id * @param float $amount * @return bool */ public function addMoney(int $order_id, float $amount) { $orderUp = OrderModel::query()->where('id', $order_id)->update([ 'total_amount' => Db::raw('total_amount + ' . $amount), 'pay_amount' => Db::raw('pay_amount + ' . $amount), 'raise_amount' => Db::raw('raise_amount + ' . $amount), 'update_time' => time() ]); if (!$orderUp) { return $this->error('操作失败'); } return $this->success('操作成功'); } public function points() { return $this->hasMany(OrderPointModel::class, 'order_id', 'id'); } public function user() { return $this->hasOne(UserModel::class, 'id', 'user_id'); } public function driver() { return $this->hasOne(DriverModel::class, 'id', 'driver_id'); } public function car_seat() { return $this->hasOne(CarSeatModel::class, 'id', 'car_seat_id'); } }