Files
anmo/server/app/shopapi/logic/CityLogic.php
2025-08-19 14:16:51 +08:00

308 lines
9.3 KiB
PHP
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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;
}
}