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.
162 lines
5.3 KiB
162 lines
5.3 KiB
11 months ago
|
<?php
|
||
|
// +----------------------------------------------------------------------
|
||
|
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||
|
// +----------------------------------------------------------------------
|
||
|
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||
|
// +----------------------------------------------------------------------
|
||
|
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||
|
// +----------------------------------------------------------------------
|
||
|
// | Author: 萤火科技 <admin@yiovo.com>
|
||
|
// +----------------------------------------------------------------------
|
||
|
declare (strict_types=1);
|
||
|
|
||
|
namespace app\api\model\store;
|
||
|
|
||
|
use app\common\model\store\Shop as ShopModel;
|
||
|
|
||
|
/**
|
||
|
* 商家门店模型
|
||
|
* Class Shop
|
||
|
* @package app\store\model\store
|
||
|
*/
|
||
|
class Shop extends ShopModel
|
||
|
{
|
||
|
/**
|
||
|
* 隐藏字段
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $hidden = [
|
||
|
'is_delete',
|
||
|
'store_id',
|
||
|
'create_time',
|
||
|
'update_time'
|
||
|
];
|
||
|
|
||
|
/**
|
||
|
* 获取门店列表
|
||
|
* @param array $param 查询参数
|
||
|
* @param int|null $limit 查询条数
|
||
|
* @return array|\think\Collection
|
||
|
* @throws \think\db\exception\DataNotFoundException
|
||
|
* @throws \think\db\exception\DbException
|
||
|
* @throws \think\db\exception\ModelNotFoundException
|
||
|
*/
|
||
|
public function getList(array $param = [], int $limit = null)
|
||
|
{
|
||
|
// 查询构造器
|
||
|
$query = $this->getNewQuery();
|
||
|
// 设置列表查询条件
|
||
|
$filter = $this->getFilter($param);
|
||
|
// 获取数量
|
||
|
$limit > 0 && $query->limit($limit);
|
||
|
// 获取门店列表数据
|
||
|
$list = $query->with(['logoImage'])
|
||
|
->where($filter)
|
||
|
->where('is_delete', '=', 0)
|
||
|
->where('status', '=', 1)
|
||
|
->order(['sort' => 'asc', $this->getPk()])
|
||
|
->select();
|
||
|
// 根据距离排序
|
||
|
if (!empty($param['longitude']) && !empty($param['latitude'])) {
|
||
|
return $this->sortByDistance($list, $param['longitude'], $param['latitude']);
|
||
|
}
|
||
|
return $list;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 设置列表查询条件
|
||
|
* @param array $param
|
||
|
* @return array
|
||
|
*/
|
||
|
private function getFilter(array $param = []): array
|
||
|
{
|
||
|
// 默认查询参数
|
||
|
$params = $this->setQueryDefaultValue($param, [
|
||
|
'isCheck' => -1, // 是否支持自提核销(0否 1支持)
|
||
|
'longitude' => '', // 用户位置: 经度
|
||
|
'latitude' => '', // 用户位置: 纬度
|
||
|
]);
|
||
|
// 检索查询条件
|
||
|
$filter = [];
|
||
|
// 是否支持自提核销
|
||
|
$params['isCheck'] > -1 && $filter[] = ['is_check', '=', (int)$params['isCheck']];
|
||
|
return $filter;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 根据距离排序
|
||
|
* @param $data
|
||
|
* @param string $longitude 经度
|
||
|
* @param string $latitude 纬度
|
||
|
* @return array
|
||
|
*/
|
||
|
private function sortByDistance($data, string $longitude, string $latitude): array
|
||
|
{
|
||
|
// 根据距离排序
|
||
|
$list = $data->isEmpty() ? [] : $data->toArray();
|
||
|
$sortArr = [];
|
||
|
foreach ($list as &$shop) {
|
||
|
// 计算距离
|
||
|
$distance = self::getDistance((float)$longitude, (float)$latitude, (float)$shop['longitude'], (float)$shop['latitude']);
|
||
|
// 排序列
|
||
|
$sortArr[] = $distance;
|
||
|
$shop['distance'] = $distance;
|
||
|
if ($distance >= 1000) {
|
||
|
$distance = bcdiv((string)$distance, (string)1000, 2);
|
||
|
$shop['distance_unit'] = $distance . 'km';
|
||
|
} else
|
||
|
$shop['distance_unit'] = $distance . 'm';
|
||
|
}
|
||
|
// 根据距离排序
|
||
|
array_multisort($sortArr, SORT_ASC, $list);
|
||
|
return $list;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 获取两个坐标点的距离
|
||
|
* @param float $ulon
|
||
|
* @param float $ulat
|
||
|
* @param float $slon
|
||
|
* @param float $slat
|
||
|
* @return float
|
||
|
*/
|
||
|
private static function getDistance(float $ulon, float $ulat, float $slon, float $slat): float
|
||
|
{
|
||
|
// 地球半径
|
||
|
$R = 6378137;
|
||
|
// 将角度转为狐度
|
||
|
$radLat1 = deg2rad($ulat);
|
||
|
$radLat2 = deg2rad($slat);
|
||
|
$radLng1 = deg2rad($ulon);
|
||
|
$radLng2 = deg2rad($slon);
|
||
|
// 结果
|
||
|
$s = acos(cos($radLat1) * cos($radLat2) * cos($radLng1 - $radLng2) + sin($radLat1) * sin($radLat2)) * $R;
|
||
|
// 精度
|
||
|
$s = round($s * 10000) / 10000;
|
||
|
return round($s);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 根据门店id集获取门店列表
|
||
|
* @param array $shopIds
|
||
|
* @return \think\Collection|false
|
||
|
* @throws \think\db\exception\DataNotFoundException
|
||
|
* @throws \think\db\exception\DbException
|
||
|
* @throws \think\db\exception\ModelNotFoundException
|
||
|
*/
|
||
|
public function getListByIds(array $shopIds)
|
||
|
{
|
||
|
if (empty($shopIds)) {
|
||
|
return false;
|
||
|
}
|
||
|
// 筛选条件
|
||
|
$filter = [['shop_id', 'in', $shopIds]];
|
||
|
// 获取商品列表数据
|
||
|
return $this->with(['logoImage'])
|
||
|
->orderRaw('field(shop_id, ' . implode(',', $shopIds) . ')')
|
||
|
->where('is_delete', '=', '0')
|
||
|
->where('status', '=', '1')
|
||
|
->where($filter)
|
||
|
->select();
|
||
|
}
|
||
|
}
|