308 lines
9.3 KiB
PHP
Executable File
308 lines
9.3 KiB
PHP
Executable File
<?php
|
||
namespace app\shopapi\logic;
|
||
use app\common\logic\BaseLogic;
|
||
use app\common\model\city\City;
|
||
use app\common\service\ConfigService;
|
||
use app\common\service\TencentMapKeyService;
|
||
use Exception;
|
||
|
||
class CityLogic extends BaseLogic
|
||
{
|
||
|
||
/**
|
||
* @notes 地级市列表
|
||
* @return array
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\DbException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
* @author ljj
|
||
* @date 2022/4/6 2:41 下午
|
||
*/
|
||
public function city($params)
|
||
{
|
||
$where = [];
|
||
$where[] = ['level','=',2];
|
||
if(isset($params['keyword']) && $params['keyword']){
|
||
$where[] = ['name','like','%'.$params['keyword'].'%'];
|
||
}
|
||
$lists = City::where($where)
|
||
->field('id,parent_id,level,name,gcj02_lng,gcj02_lat,db09_lng,db09_lat')
|
||
->select()
|
||
->toArray();
|
||
|
||
$lists = self::groupByInitials($lists);
|
||
unset($lists[null]);
|
||
|
||
return $lists;
|
||
}
|
||
|
||
/*
|
||
* 二维数组根据首字母分组排序
|
||
* @param array $data 二维数组
|
||
* @param string $targetKey 首字母的键名
|
||
* @return array 根据首字母关联的二维数组
|
||
*/
|
||
public function groupByInitials(array $data, $targetKey = 'name')
|
||
{
|
||
$data = array_map(function ($item) use ($targetKey) {
|
||
return array_merge($item, [
|
||
'initials' => $this->getInitials($item[$targetKey]),
|
||
]);
|
||
}, $data);
|
||
$data = $this->sortInitials($data);
|
||
return $data;
|
||
}
|
||
|
||
/**
|
||
* 按字母排序
|
||
* @param array $data
|
||
* @return array
|
||
*/
|
||
public function sortInitials(array $data)
|
||
{
|
||
$sortData = [];
|
||
foreach ($data as $key => $value) {
|
||
$sortData[$value['initials']][] = $value;
|
||
}
|
||
ksort($sortData);
|
||
return $sortData;
|
||
}
|
||
|
||
/**
|
||
* 获取首字母
|
||
* @param string $str 汉字字符串
|
||
* @return string 首字母
|
||
*/
|
||
public function getInitials($str)
|
||
{
|
||
if (empty($str)) {return '';}
|
||
$fchar = ord($str[0]);
|
||
if ($fchar >= ord('A') && $fchar <= ord('z')) {
|
||
return strtoupper($str[0]);
|
||
}
|
||
|
||
$s1 = iconv('UTF-8', 'GBK', $str);
|
||
$s2 = iconv('GBK', 'UTF-8', $s1);
|
||
$s = $s2 == $str ? $s1 : $str;
|
||
$asc = ord($s[0]) * 256 + ord($s[1]) - 65536;
|
||
if ($asc >= -20319 && $asc <= -20284) {
|
||
return 'A';
|
||
}
|
||
if ($asc >= -20283 && $asc <= -19776) {
|
||
return 'B';
|
||
}
|
||
if ($asc >= -19775 && $asc <= -19219) {
|
||
return 'C';
|
||
}
|
||
if ($asc >= -19218 && $asc <= -18711) {
|
||
return 'D';
|
||
}
|
||
if ($asc >= -18710 && $asc <= -18527) {
|
||
return 'E';
|
||
}
|
||
if ($asc >= -18526 && $asc <= -18240) {
|
||
return 'F';
|
||
}
|
||
if ($asc >= -18239 && $asc <= -17923) {
|
||
return 'G';
|
||
}
|
||
if ($asc >= -17922 && $asc <= -17418) {
|
||
return 'H';
|
||
}
|
||
if ($asc >= -17417 && $asc <= -16475) {
|
||
return 'J';
|
||
}
|
||
if ($asc >= -16474 && $asc <= -16213) {
|
||
return 'K';
|
||
}
|
||
if ($asc >= -16212 && $asc <= -15641) {
|
||
return 'L';
|
||
}
|
||
if ($asc >= -15640 && $asc <= -15166) {
|
||
return 'M';
|
||
}
|
||
if ($asc >= -15165 && $asc <= -14923) {
|
||
return 'N';
|
||
}
|
||
if ($asc >= -14922 && $asc <= -14915) {
|
||
return 'O';
|
||
}
|
||
if ($asc >= -14914 && $asc <= -14631) {
|
||
return 'P';
|
||
}
|
||
if ($asc >= -14630 && $asc <= -14150) {
|
||
return 'Q';
|
||
}
|
||
if ($asc >= -14149 && $asc <= -14091) {
|
||
return 'R';
|
||
}
|
||
if ($asc >= -14090 && $asc <= -13319) {
|
||
return 'S';
|
||
}
|
||
if ($asc >= -13318 && $asc <= -12839) {
|
||
return 'T';
|
||
}
|
||
if ($asc >= -12838 && $asc <= -12557) {
|
||
return 'W';
|
||
}
|
||
if ($asc >= -12556 && $asc <= -11848) {
|
||
return 'X';
|
||
}
|
||
if ($asc >= -11847 && $asc <= -11056) {
|
||
return 'Y';
|
||
}
|
||
if ($asc >= -11055 && $asc <= -10247) {
|
||
return 'Z';
|
||
}
|
||
return null;
|
||
}
|
||
/**
|
||
* @notes 城市列表
|
||
* @return array
|
||
* @throws \think\db\exception\DataNotFoundException
|
||
* @throws \think\db\exception\DbException
|
||
* @throws \think\db\exception\ModelNotFoundException
|
||
* @author cjhao
|
||
* @date 2024/11/6 10:55
|
||
*/
|
||
public function getCityLists()
|
||
{
|
||
$lists = City::where(['level'=>2])->select()->toArray();
|
||
$cityLists = [];
|
||
foreach ($lists as $city){
|
||
$parent = $cityLists[$city['parent_id']] ?? [];
|
||
if($parent){
|
||
$parent['sons'][] =[
|
||
'id' => $city['city_id'],
|
||
'name' => $city['name'],
|
||
];
|
||
}else{
|
||
$parent = [
|
||
'id' => $city['parent_id'],
|
||
'name' => $city['parent_name'],
|
||
'sons' => [
|
||
[
|
||
'id' => $city['city_id'],
|
||
'name' => $city['name'],
|
||
],
|
||
],
|
||
];
|
||
}
|
||
$cityLists[$city['parent_id']] = $parent;
|
||
}
|
||
return array_values($cityLists);
|
||
}
|
||
|
||
|
||
/**
|
||
* @notes 获取当前位置最近的城市
|
||
* @param $get
|
||
* @return array|false
|
||
* @author cjhao
|
||
* @date 2024/9/3 22:58
|
||
*/
|
||
public function getNearbyCity($get)
|
||
{
|
||
try {
|
||
$longitude = $get['longitude'] ?? '';
|
||
$latitude = $get['latitude'] ?? '';
|
||
if(empty($longitude) || empty($latitude)){
|
||
throw new Exception('请授权获取位置');
|
||
}
|
||
$cityLists = \app\common\logic\CityLogic::getNearbyCity($longitude,$latitude);
|
||
return $cityLists[0] ?? [];
|
||
|
||
}catch (Exception $e){
|
||
self::$error = $e->getMessage();
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @notes 搜索附近地址
|
||
* @param $params
|
||
* @return array|mixed
|
||
* @author ljj
|
||
* @date 2024/7/23 上午11:20
|
||
*/
|
||
public function getNearbyLocation($params)
|
||
{
|
||
$longitude = $params['longitude'] ?? '';
|
||
$latitude = $params['latitude'] ?? '';
|
||
if(empty($longitude) || empty($latitude)){
|
||
throw new Exception('请授权获取位置');
|
||
}
|
||
//开发秘钥
|
||
$data['key'] = (new TencentMapKeyService())->getTencentMapKey();
|
||
if (empty($data['key'])) {
|
||
return ['status'=>1,'message'=>'腾讯地图开发密钥不能为空'];
|
||
}
|
||
|
||
//排序,按距离由近到远排序
|
||
$data['orderby'] = '_distance';
|
||
//排序,按距离由近到远排序
|
||
$data['boundary'] = "nearby(" . $params['latitude'] . "," . $params['longitude'] . ",1000,1)";
|
||
//搜索关键字
|
||
$keyword = $params['keyword'] ?? '';
|
||
//api地址
|
||
//未输入搜索关键词时,默认使用周边推荐api
|
||
$url = 'https://apis.map.qq.com/ws/place/v1/explore';
|
||
|
||
if (!empty($keyword)) {
|
||
$data['keyword'] = $keyword;
|
||
//输入搜索关键词时,使用周边搜索api
|
||
$url = 'https://apis.map.qq.com/ws/place/v1/search';
|
||
}
|
||
$query = http_build_query($data);
|
||
$result = json_decode(file_get_contents($url . '?' . $query), true);
|
||
if ($result['status'] !== 0) {
|
||
$check = (new TencentMapKeyService())->checkResult($result);
|
||
while (!$check) {
|
||
$data['key'] = (new TencentMapKeyService())->getTencentMapKey(true);
|
||
if (empty($data['key'])) {
|
||
break;
|
||
}
|
||
|
||
$query = http_build_query($data);
|
||
$result = json_decode(file_get_contents($url . '?' . $query), true);
|
||
$check = (new TencentMapKeyService())->checkResult($result);
|
||
}
|
||
}
|
||
return $result;
|
||
}
|
||
|
||
/**
|
||
* @notes 逆地址解析(坐标位置描述)
|
||
* @param $get
|
||
* @return array|mixed
|
||
* @author ljj
|
||
* @date 2022/10/13 2:44 下午
|
||
* 本接口提供由经纬度到文字地址及相关位置信息的转换能力
|
||
*/
|
||
public static function geocoderCoordinate($get)
|
||
{
|
||
$get['key'] = (new TencentMapKeyService())->getTencentMapKey();
|
||
if (empty($get['key'])) {
|
||
return ['status'=>1,'message'=>'腾讯地图开发密钥不能为空'];
|
||
}
|
||
|
||
$query = http_build_query($get);
|
||
$url = 'https://apis.map.qq.com/ws/geocoder/v1/';
|
||
$result = json_decode(file_get_contents($url.'?'.$query),true);
|
||
if ($result['status'] !== 0) {
|
||
$check = (new TencentMapKeyService())->checkResult($result);
|
||
while (!$check) {
|
||
$data['key'] = (new TencentMapKeyService())->getTencentMapKey(true);
|
||
if (empty($data['key'])) {
|
||
break;
|
||
}
|
||
|
||
$query = http_build_query($data);
|
||
$result = json_decode(file_get_contents($url . '?' . $query), true);
|
||
$check = (new TencentMapKeyService())->checkResult($result);
|
||
}
|
||
}
|
||
return $result;
|
||
}
|
||
} |