Laravel 数据库计算坐标距离并排序

74 篇文章 0 订阅

<?php
namespace App\Models\v2;

use App\Models\BaseModel;
use App\Models\v2\GoodsShop;

class Shop extends BaseModel
{

    protected $connection = 'shop';

    protected $table = 'shop';

    public $timestamps = false;

    /**
     * 门店列表
     *
     * @param array $attributes
     *            [description]
     * @return [type] [description]
     */
    public static function getList(array $attributes)
    {
        extract($attributes);
        
        // 地区编码
        if (! isset($city) || ! $city) {
            return self::formatError(100001, '地区编码不能为空!');
        }
        
        $model = self::where([
            'status' => 1,
            'city' => $city
        ]);
        $total = $model->count();
        // 获取select字段
        $model->select(self::getSelect($latitude, $longitude));
        
        // orderby
        if (isset($user_distant) && $user_distant) {
            $model->orderBy("user_distant", "asc");
        } else {
            $model->orderBy("shop_id", "desc");
        }

        $data = $model->paginate($per_page)->toArray();
        
        return self::formatBody([
            'list' => $data['data'],
            'paged' => self::formatPaged($page, $per_page, $total)
        ]);
    }

    /**
     * 门店搜索列表
     *
     * @param array $attributes
     *            [description]
     * @return [type] [description]
     */
    public static function getSearchList(array $attributes)
    {
        extract($attributes);
        
        // 地区编码
        if (! isset($city) || ! $city) {
            return self::formatError(100001, '地区编码不能为空!');
        }
        if (! isset($keyword) || ! $keyword) {
            return self::formatError(100001, '搜索内容不能为空!');
        }
        
        $model = self::where([
            'status' => 1,
            'city' => $city
        ])->where(function ($query) use ($keyword) {
            // keywords
            $query->where('shop_name', 'like', '%' . strip_tags($keyword) . '%');
        });
        
        $total = $model->count();
        
        // 获取select字段
        $model->select(self::getSelect($latitude, $longitude));
        
        // orderby
        if (isset($user_distant) && $user_distant) {
            $model->orderBy("user_distant", "asc");
        } else {
            $model->orderBy("shop_id", "desc");
        }
        
        $data = $model->paginate($per_page)->toArray();
        
        return self::formatBody([
            'list' => $data['data'],
            'paged' => self::formatPaged($page, $per_page, $total)
        ]);
    }

    /**
     * 门店搜索地址列表
     *
     * @param array $attributes
     *            [description]
     * @return [type] [description]
     */
    public static function getSearchListAddress(array $attributes)
    {
        extract($attributes);
        
        // 地区编码
        if (! isset($goods_id) || ! $goods_id) {
            return self::formatError(100001, '产品信息错误!');
        }
        
        if (! isset($keyword) || ! $keyword) {
            $keyword = '';
        }
        
        $model = GoodsShop::leftJoin('shop', 'goods_shop.shop_id', '=', 'shop.shop_id')->where('goods_shop.goods_id', $goods_id)
            ->where('shop.status', 1)
            ->where(function ($query) use ($keyword) {
            // keywords
            if ($keyword) {
                $query->where('shop.shop_name', 'like', '%' . strip_tags($keyword) . '%');
            }
        });
            
        $total = $model->count();
        
        // 获取select字段
        $model->select(self::getSelectAddress($latitude, $longitude));
        
        // orderby
        if (isset($user_distant) && $user_distant) {
            $model->orderBy("user_distant", "asc");
        } else {
            $model->orderBy("shop.shop_id", "desc");
        }
        
        $data = $model->paginate($per_page)->toArray();
        
        return self::formatBody([
            'list' => $data['data'],
            'paged' => self::formatPaged($page, $per_page, $total)
        ]);
    }

    /**
     * 门店详情
     *
     * @param array $attributes
     *            [description]
     * @return [type] [description]
     */
    public static function getDetail(array $attributes)
    {
        extract($attributes);
        
        $data = self::where('shop_id', $shop_id)->first()->toArray();
        // 获取门店商品
        $goods = GoodsShop::leftJoin('goods', 'goods_shop.goods_id', '=', 'goods.goods_id')->where('goods_shop.shop_id', $shop_id)
            ->where('goods.is_on_sale', 1)
            ->select('goods_shop.*', 'goods.goods_name', 'goods.market_price', 'goods.shop_price', 'goods.goods_thumb', 'goods.goods_brief', 'goods.get_method')
            ->get()
            ->toArray();
        
        return self::formatBody([
            'info' => $data,
            'goods' => $goods
        ]);
    }

    /**
     * 门店地址
     *
     * @param array $attributes
     *            [description]
     * @return [type] [description]
     */
    public static function getAddress(array $attributes)
    {
        extract($attributes);
        
        $data = self::where('shop_id', $shop_id)->first([
            'shop_id',
            'shop_name',
            'address',
            'lng',
            'lat',
            'contact_man',
            'contact_phone'
        ])->toArray();
        
        return self::formatBody([
            'info' => $data
        ]);
    }

    public static function getSelect($lat, $lng)
    {
        if ($lat && $lng) {
            $select = [
                '*',
                \DB::raw("ROUND(
                    6378.138 * 2 * ASIN(
                    SQRT(
                    POW(
                    SIN(
                    (
                    {$lat} * PI() / 180 - lat * PI() / 180
                    ) / 2
                    ),
                    2
                    ) + COS({$lat} * PI() / 180) * COS(lat * PI() / 180) * POW(
                    SIN(
                    (
                    {$lng} * PI() / 180 - lng * PI() / 180
                    ) / 2
                    ),
                    2
                    )
                    )
                    ) * 1000
                    ) AS user_distant")
            ];
        } else {
            $select = [
                '*',
                \DB::raw("'0' as user_distant")
            ];
        }
        return $select;
    }
    
    public static function getSelectAddress($lat, $lng)
    {
        if ($lat && $lng) {
            $select = [
                'goods_shop.*',
                'shop.logo',
                'shop.shop_name',
                'shop.address',
                'shop.lng',
                'shop.lat',
                'shop.contact_man',
                'shop.contact_phone',
                \DB::raw("ROUND(
                    6378.138 * 2 * ASIN(
                    SQRT(
                    POW(
                    SIN(
                    (
                    {$lat} * PI() / 180 - (`ecs_shop`.lat) * PI() / 180
                    ) / 2
                    ),
                    2
                    ) + COS({$lat} * PI() / 180) * COS((`ecs_shop`.lat) * PI() / 180) * POW(
                    SIN(
                    (
                    {$lng} * PI() / 180 - (`ecs_shop`.lng) * PI() / 180
                    ) / 2
                    ),
                    2
                    )
                    )
                    ) * 1000
                    ) AS user_distant")
                    ];
        } else {
            $select = [
                'goods_shop.*',
                'shop.logo',
                'shop.shop_name',
                'shop.address',
                'shop.lng',
                'shop.lat',
                'shop.contact_man',
                'shop.contact_phone',
                \DB::raw("'0' as user_distant")
            ];
        }
        return $select;
    }
}
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梅坞茶坊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值