Fastadmin Area模型返回没值 没对象georadius 源码里面没有$redis->geoadd 解决办法

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

添加后的成功截图:

 

 

 

 

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

citydata 为空;

 

 

 

赶紧看了接口代码 

官方里面代码如下:

 1 <?php
 2 
 3 namespace app\api\controller;
 4 
 5 use app\common\controller\Api;
 6 use app\common\model\Area;
 7 use app\common\model\Version;
 8 use fast\Random;
 9 use think\Config;
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     }

 

调用了

app\common\model\Area 下面的getCityFromLngLat方法

官方代码如下:
 1 use think\Cache;
 2 use think\Model;
 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 think\Db;
数据库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 think\Db;  这个要有数据哦,没数据可以在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可以试着获取),

修改app\common\model\Area.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();//这个注释了是因为配置 缓存没去看怎么配置(略看了下,有点复杂)只是获取地区的时候才用这个 所以加入的,更具情况而定
 

 

 
posted @ 2021-01-22 14:33  xiaohe520  阅读(842)  评论(0编辑  收藏  举报