You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
8.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
/**
* 其他
*/
namespace App\Http\Controllers\Mobile;
use App\Helpers\ResponseCode;
use App\Models\AppointmentConfig;
use App\Models\AppointmentType;
use App\Models\Banner;
use App\Models\Company;
use App\Models\Config;
use App\Models\CourseType;
use App\Repositories\YuanheRepository;
use Illuminate\Support\Facades\Validator;
class OtherController extends CommonController
{
/**
* @OA\Get(
* path="/api/mobile/other/config",
* tags={"小程序-其他"},
* summary="获取配置信息",
* @OA\Parameter(name="appointment_type_id", in="query", @OA\Schema(type="integer"), required=true, description="场地类型"),
* @OA\Response(
* response=200,
* description="操作成功"
* )
* )
*/
public function config()
{
$all = request()->all();
$config = Config::get();
$appointment = AppointmentConfig::where(function ($query) use ($all) {
if (isset($all['appointment_type_id'])) {
$query->where('appointment_type_id', $all['appointment_type_id']);
}
})->where('show_front', 1)->get();
// 场地类型
$appointment_type = AppointmentType::get();
// 获取开放手机号的课程体系
$course_types_open_mobile = CourseType::where('open_mobile', 1)->get();
return $this->success(compact('config', 'appointment', 'appointment_type', 'course_types_open_mobile'));
}
/**
* @OA\Get(
* path="/api/mobile/other/banner",
* tags={"小程序-其他"},
* summary="获取banner",
* @OA\Parameter(name="position", in="query", @OA\Schema(type="integer"), required=true, description="位置1首页"),
* @OA\Response(
* response=200,
* description="操作成功"
* )
* )
*/
public function banner()
{
$position = request('position', 1);
$config = Banner::with('image')->where(function ($query) use ($position) {
if (isset($position)) {
$query->where('position', $position);
}
})->orderBy('sort')->get();
return $this->success($config);
}
/**
* @OA\Get(
* path="/api/mobile/other/company",
* tags={"小程序-其他"},
* summary="公司搜索",
* @OA\Parameter(name="company_name", in="query", @OA\Schema(type="integer"), required=true, description="公司名字"),
* @OA\Response(
* response=200,
* description="操作成功"
* )
* )
*/
public function company()
{
$all = \request()->all();
$messages = [
'company_name.required' => '公司名称必填',
];
$validator = Validator::make($all, [
'company_name' => 'required',
], $messages);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$YuanheRepository = new YuanheRepository();
$result = $YuanheRepository->search(['keyword' => $all['company_name']]);
$result = json_decode($result, true);
if (!$result) {
return $this->fail([ResponseCode::ERROR_PARAMETER, '获取失败']);
}
return $this->success($result);
}
/**
* @OA\Get(
* path="/api/mobile/other/company-list",
* tags={"小程序-其他"},
* summary="公司列表",
* @OA\Parameter(name="company_name", in="query", @OA\Schema(type="string"), required=false, description="公司名字"),
* @OA\Parameter(name="company_longitude", in="query", @OA\Schema(type="string"), required=false, description="经度"),
* @OA\Parameter(name="company_latitude", in="query", @OA\Schema(type="string"), required=false, description="纬度"),
* @OA\Parameter(name="page_size", in="query", @OA\Schema(type="string"), required=false, description="每页显示的条数"),
* @OA\Parameter(name="page", in="query", @OA\Schema(type="string"), required=false, description="页码"),
* @OA\Parameter(name="sort_name", in="query", @OA\Schema(type="string"), required=false, description="排序字段名字"),
* @OA\Parameter(name="sort_type", in="query", @OA\Schema(type="string"), required=false, description="排序类型"),
* @OA\Response(
* response=200,
* description="操作成功"
* )
* )
*/
public function companyList()
{
$all = \request()->all();
$messages = [
'company_longitude.required' => '经度必填',
'company_latitude.required' => '纬度必填',
];
$validator = Validator::make($all, [
'company_longitude' => 'required',
'company_latitude' => 'required',
], $messages);
if ($validator->fails()) {
return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]);
}
$longitude = floatval($all['company_longitude']);
$latitude = floatval($all['company_latitude']);
$pageSize = intval($all['page_size'] ?? 10);
$page = intval($all['page'] ?? 1);
$sortName = $all['sort_name'] ?? 'distance';
$sortType = $all['sort_type'] ?? 'asc';
// 构建基础查询
$query = Company::select('id', 'company_name', 'company_longitude', 'company_latitude', 'company_address')
->where(function ($query) use ($all) {
if (isset($all['company_name'])) {
$query->where('company_name', 'like', '%' . $all['company_name'] . '%');
}
})->whereNotNull('company_longitude')
->whereNotNull('company_latitude')
->where('company_longitude', '!=', '')
->where('company_latitude', '!=', '')
->whereRaw('CAST(company_longitude AS DECIMAL(10,8)) BETWEEN -180 AND 180')
->whereRaw('CAST(company_latitude AS DECIMAL(10,8)) BETWEEN -90 AND 90')
->whereHas('users', function ($query) {
$query->where('is_schoolmate', 1);
})->with([
'users' => function ($query) {
$query->select('id', 'name', 'username', 'company_position', 'company_id')->where('is_schoolmate', 1)->with([
'courseSigns' => function ($query) {
$query->select('id', 'status', 'user_id', 'course_id')->with('course')->orderBy('fee_status', 'desc');
}
]);
}
]);
// 根据排序字段进行排序
if ($sortName !== 'distance') {
$query->orderBy($sortName, $sortType);
}
$result = $query->paginate($pageSize, ['*'], 'page', $page);
// 在PHP中计算距离并优化性能
$latRad = deg2rad($latitude);
$lonRad = deg2rad($longitude);
$cosLat = cos($latRad);
$sinLat = sin($latRad);
foreach ($result->items() as $company) {
$companyLat = floatval($company->company_latitude);
$companyLon = floatval($company->company_longitude);
// 验证经纬度有效性
if ($companyLat < -90 || $companyLat > 90 || $companyLon < -180 || $companyLon > 180) {
$company->distance = null;
continue;
}
// 预计算三角函数值以提高性能
$companyLatRad = deg2rad($companyLat);
$companyLonRad = deg2rad($companyLon);
$acosInput = $cosLat * cos($companyLatRad) * cos($companyLonRad - $lonRad) +
$sinLat * sin($companyLatRad);
// 确保acos输入值在有效范围内
$acosInput = max(-1, min(1, $acosInput));
$distance = 6371 * acos($acosInput);
$company->distance = round($distance, 2); // 保留两位小数
}
// 如果按距离排序在PHP中排序
if ($sortName === 'distance') {
$items = $result->items();
usort($items, function ($a, $b) {
// 处理无效距离的情况
if ($a->distance === null && $b->distance === null)
return 0;
if ($a->distance === null)
return 1;
if ($b->distance === null)
return -1;
return $a->distance <=> $b->distance;
});
$result->setCollection(collect($items));
}
return $this->success($result);
}
}