zoukankan      html  css  js  c++  java
  • Fastadmin Area模型返回没值 没对象georadius 源码里面没有$redis->geoadd 解决办法

    解决办法:我们只需要在redis里面添加坐标数据即可,添加这三个键(geo:province    geo:city   geo:district)

    添加后的成功截图:

    由于项目要用到坐标,Fastadmin看官方提供了一个接口默认地址 /api/common/init  ,(可以在自己的域名后加入/api.html),然后提交了经纬度,如图:

    citydata 为空;

    赶紧看了接口代码 

    官方里面代码如下:

     1 <?php
     2 
     3 namespace appapicontroller;
     4 
     5 use appcommoncontrollerApi;
     6 use appcommonmodelArea;
     7 use appcommonmodelVersion;
     8 use fastRandom;
     9 use thinkConfig;
    10 
    11 /**
    12  * 公共接口
    13  */
    14 class Common extends Api
    15 {
    16     protected $noNeedLogin = ['init'];
    17     protected $noNeedRight = '*';
    18 
    19     /**
    20      * 加载初始化
    21      *
    22      * @param string $version 版本号
    23      * @param string $lng     经度
    24      * @param string $lat     纬度
    25      */
    26     public function init()
    27     {
    28         if ($version = $this->request->request('version')) {
    29             $lng = $this->request->request('lng');
    30             $lat = $this->request->request('lat');
    31             $content = [
    32                 'citydata'    => Area::getCityFromLngLat($lng, $lat),
    33                 'versiondata' => Version::check($version),
    34                 'uploaddata'  => Config::get('upload'),
    35                 'coverdata'   => Config::get("cover"),
    36             ];
    37             $this->success('', $content);
    38         } else {
    39             $this->error(__('Invalid parameters'));
    40         }
    41     }

    调用了

    appcommonmodelArea 下面的getCityFromLngLat方法

    官方代码如下:
     1 use thinkCache;
     2 use thinkModel;
     3 
     4 /**
     5  * 地区数据模型
     6  */
     7 class Area extends Model
     8 {
     9 
    10     /**
    11      * 根据经纬度获取当前地区信息
    12      *
    13      * @param string $lng 经度
    14      * @param string $lat 纬度
    15      * @return Area 城市信息
    16      */
    17     public static function getAreaFromLngLat($lng, $lat, $level = 3)
    18     {
    19         $namearr = [1 => 'geo:province', 2 => 'geo:city', 3 => 'geo:district'];
    20         $rangearr = [1 => 15000, 2 => 1000, 3 => 200];
    21         $geoname = isset($namearr[$level]) ? $namearr[$level] : $namearr[3];
    22         $georange = isset($rangearr[$level]) ? $rangearr[$level] : $rangearr[3];
    23         // 读取范围内的ID
    24         $redis = Cache::store('redis')->handler();
    25         $georadiuslist = [];
    26         if (method_exists($redis, 'georadius')) {
    27             $georadiuslist = $redis->georadius($geoname, $lng, $lat, $georange, 'km', ['WITHDIST', 'COUNT' => 5, 'ASC']);
    28         }
    29 
    30         if ($georadiuslist) {
    31             list($id, $distance) = $georadiuslist[0];
    32         }
    33         $id = isset($id) && $id ? $id : 3;
    34         return self::get($id);
    35     }
    
    

    然发现24行的 $redis用不了,原因有几(没安装redis,安装了密码端口被更改了,还是有就是config.php 里面的缓存模式是File,还有看切换类型要个缓存模式配置,放弃了... )

    不能在分析了没时间 ,不然得加班了! 

    /****************************************************分割线******************************************************

    扯远了,其实我们只需要在redis里面添加坐标数据即可 ,

    由于这个项目只需要坐标用到redis就懒得切换研究了

    直接原生的办法添加数据的代码只需要执行一次,也就是添加到redis里面:

    代码如下:

    //Db记得 use thinkDb;
    数据库area这个表要有数据哦(fastadmin提供了3k多个数据{经过后期测试,详细的某个地区坐标,还是有偏差,简单来说数据有点问题,(如果要数据准,要在某个区域添加n个坐标,这样才能准确,全国这么多个市区,所以代码示例里面也就到市区)现在理解为啥要自己导入了!}),没数据可以在fastadmin的插件里面有个<开发示例>插件安装即可
     1         $redis = new Redis;
     2         $options = [
     3             'host'        => '127.0.0.1',
     4             'port'        => 6379,
     5             'password'    => '',
     6             'select'      => 0,
     7             'timeout'     => 0,
     8             'expire'      => 0,
     9             'persistent'  => false,
    10             'userprefix'  => 'up:',
    11             'tokenprefix' => 'tp:',
    12         ];
    13         $redis->pconnect($options['host'], $options['port'], $options['timeout'], 'persistent_id_' . $options['select']);
    14         // $redis->connect($options['host'], $options['port'], $options['timeout']);//非持久化
    15         
    16         $list1 = Db::name('area')->where('level',1)->select();//Db记得 use thinkDb;  这个要有数据哦,没数据可以在fastadmin的插件里面有个<开发示例>插件安装即可
    17         foreach ($list1 as $key => $val) {
    18             // halt((float)$val['lng']);
    19             $redis->geoadd('geo:province',(float)$val['lng'],(float)$val['lat'],$val['id']);
    20         }
    21 
    22         $list2 = Db::name('area')->where('level',2)->select();
    23         foreach ($list2 as $key => $val) {
    24             $redis->geoadd('geo:city',(float)$val['lng'],(float)$val['lat'],$val['id']);
    25         }
    26 
    27         $list3 = Db::name('area')->where('level',3)->select();
    28         foreach ($list3 as $key => $val) {
    29             $redis->geoadd('geo:district',(float)$val['lng'],(float)$val['lat'],$val['id']);
    30         }
    31         echo ("导入成功"."欢迎加入QQ群交流:153073132");

    然后获取的时候我也稍微修改了下(更具自己项目缓存而定 个人没有用redis来作为缓存所以采用以下修改,如果用的非File可以试着获取),

    修改appcommonmodelArea.php代码如下:

     1     /**
     2      * 根据经纬度获取当前地区信息
     3      *
     4      * @param string $lng 经度
     5      * @param string $lat 纬度
     6      * @return Area 城市信息
     7      */
     8     public static function getAreaFromLngLat($lng, $lat, $level = 3)
     9     {
    10 
    11         $namearr = [1 => 'geo:province', 2 => 'geo:city', 3 => 'geo:district'];
    12         $rangearr = [1 => 15000, 2 => 1000, 3 => 200];
    13         $geoname = isset($namearr[$level]) ? $namearr[$level] : $namearr[3];
    14         $georange = isset($rangearr[$level]) ? $rangearr[$level] : $rangearr[3];
    15         // 读取范围内的ID
    16         // $redis = Cache::store('redis')->handler();//原来的这个我注释了 只是获取地区的时候才用这个
    17         
    18         //添加的开始     欢迎加入QQ群交流:153073132
    19         $options = [
    20             'host'        => '127.0.0.1',
    21             'port'        => 6379,
    22             'password'    => '',
    23             'select'      => 0,
    24             'timeout'     => 0,
    25             'expire'      => 0,
    26             'persistent'  => false,
    27             'userprefix'  => 'up:',
    28             'tokenprefix' => 'tp:',
    29         ];
    30         $redis = new Redis;
    31         $redis->pconnect($options['host'], $options['port'], $options['timeout'], 'persistent_id_' . $options['select']);
    32         //添加的结束     欢迎加入QQ群交流:153073132
    33 
    34         $georadiuslist = [];
    35         if (method_exists($redis, 'georadius')) {
    36             $georadiuslist = $redis->georadius($geoname, $lng, $lat, $georange, 'km', ['WITHDIST', 'COUNT' => 5, 'ASC']);
    37         }else{
    38             halt('redis没有georadius');
    39         }
    40 
    41         if ($georadiuslist) {
    42             list($id, $distance) = $georadiuslist[0];
    43         }
    44         $id = isset($id) && $id ? $id : 3;
    45         return self::get($id);
    46     }

    就相当于只是加入了导入的数据,因为注释的,我没用混合模式

     $redis = Cache::store('redis')->handler();//这个注释了是因为配置 缓存没去看怎么配置(略看了下,有点复杂)只是获取地区的时候才用这个 所以加入的,更具情况而定
     
     
  • 相关阅读:
    LeetCode1051. 高度检查器 Java
    LeetCode 面试题 16.04. 井字游戏 Java
    WPF 显示3D密集场景,堆场管理系统
    WPF 饼状图,柱形图,折线图 (3 饼状图)
    WPF 饼状图,柱形图,折线图 (2 折线图)
    WPF 饼状图,柱形图,折线图 (1 柱形图)
    wpf 实现控件拖拽(仿windows 桌面图标拖拽)
    设计模式-控制反转
    Socket 网络编程和IO模型
    wpf 滚动文字 跑马灯
  • 原文地址:https://www.cnblogs.com/xiaohe520/p/14313156.html
Copyright © 2011-2022 走看看