AdministrativeDivision.php 7.9 KB
<?php
/**
+-----------------------------------------------------------------------------------------------------------------------
 * 模型层:系统-行政区划模型类 模型类
+-----------------------------------------------------------------------------------------------------------------------
 *
 * PHP version 7
 *
 * @category  App\Models\System
 * @package   App\Models\System
 * @author    Richer <yangzi1028@163.com>
 * @date      2021年12月17日10:01:57
 * @copyright 2020-2022 Richer (http://www.Richer.com/)
 * @license   http://www.Richer.com/ License
 * @link      http://www.Richer.com/
 */
namespace App\Models\System;

use App\Models\BaseModel;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;

/**
 * Class AdministrativeDivision
 *
 * @category  App\Models\System
 * @package   App\Models\System
 * @author    Richer <yangzi1028@163.com>
 * @date      2021年12月17日10:01:57
 * @copyright 2020-2022 Richer (http://www.Richer.com/)
 * @license   http://www.Richer.com/ License
 * @link      http://www.Richer.com/
 */
class AdministrativeDivision extends BaseModel
{
    // 指定数据库表
    protected $table = 'system_administrative_divisions';


    /**
     * 定义省市区商圈的层级
     */

    const PROVINCE      = 'province';// 省
    const CITY          = 'city';// 市
    const COUNTY      = 'county';// 区县
    const LEVEL_PROVINCE = 1;
    const LEVEL_CITY = 2;
    const LEVEL_COUNTY = 3;
    const LEVEL_OPTIONS = [
        self::PROVINCE      => self::LEVEL_PROVINCE,
        self::CITY         => self::LEVEL_CITY,
        self::COUNTY      => self::LEVEL_COUNTY,
    ];

    // 设置缓存保存时间
    const  MINUTES = 60 * 60 * 24 * 360 ;// 360天 : 1分钟 * 60 * 24 * 360

    /**
     * @return BelongsTo
     */
    public function province()
    {
        return $this->belongsTo(AdministrativeDivision::class, 'pcode', 'code');
    }

    /**
     * @return BelongsTo
     */
    public function city()
    {
        return $this->belongsTo(AdministrativeDivision::class, 'pcode', 'code');
    }

    /**
     * 定义关联模型:用户分佣记录
     *
     * @return HasMany
     */
    public function cities()
    {
        return $this->hasMany(AdministrativeDivision ::class, 'pcode', 'code');
    }

    /**
     * 定义关联模型:用户分佣记录
     *
     * @return HasMany
     */
    public function counties()
    {
        return $this->hasMany(AdministrativeDivision ::class, 'pcode', 'code');
    }

    /**
     * 获取行政区域列表-select-option
     * 主要为laravel-admin select控件使用,数据格式有两种:
     * 1、一种是在初始化的时候用格式为['110100'=>'北京市'],
     *   主要在编辑页面用,通过上级的code获取到该options并渲染到select控件中。
     * 2、第二种是联动的数据,数据格式为[{"id": 110100,"text": "北京市"}],
     *   通常用着select控件在选择的时候触发的事件调用
     *
     * @param  string $type       行政区域类型:province,city,district,bizdistrict
     * @param  string $pcode      上级 code
     * @param  string $operate    当前获取数据的方法,默认是联动获取数据。如果是init说明是初始化option
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public function getSelectOptions($type = 'province', $pcode = '', $operate = 'load')
    {
        // 设置缓存保存时间
        $minutes = self::MINUTES;

        // 定义缓存key
        $cache_key = 'admin_select_options_' . $type .'_'.$operate .'_all';

        // 如果有上级code
        if ($pcode) {
            $cache_key = 'admin_select_options_' . $type .'_'.$operate .'_'.$pcode;
        }
        //dump($cache_key);
        // 从 Cache 中获取
        $options = Cache::get($cache_key);
//        $options = [];
        //dump($options);

        // 在缓存中获取到,直接返回
        if (is_array($options) && !empty($options)) {
            return $options;
        }

        //根据不同的类别
        $level = $this -> getLevel($type);

        $fields     = ['code', 'name','initial'];
        $orderby    = 'initial,name';
        $where['level'] = $level;
        if ($pcode) {
            $where['pcode'] =$pcode;
        }

        // 如果是load方法,
        // if ($operate == 'load') {
        //     $where['pcode'] =$pcode;
        // }
        if ($pcode) {
            $where['pcode'] =$pcode;
        }

        if (request('keyword')) {
            $where[] = ['name','LIKE', '%'.request('keyword').'%'];
        }

        $list = AdministrativeDivision::where($where)->orderByRaw($orderby)->get($fields);


        if ($list) {
            if ($operate == 'init') {
                foreach ($list as $vo) {
                    $options[$vo->code] = $vo->initial.'-'.$vo->name;
                }
            } else {
                foreach ($list as $key => $vo) {
                    $options[$key]['id']    = $vo->code;
                    $options[$key]['text']  = $vo->initial.'-'.$vo->name;
                }
            }
            Cache::put($cache_key, $options, $minutes);
        }
        if (empty($options)) {
            if ($operate == 'init') {
                $options[0] = '全部';
            } else {
                $options[0]['id'] = '';
                $options[0]['text'] = '全部';
            }
        }

        return $options;
    }

    /**
     * 获取行政区域列表-select-option
     * 主要为laravel-admin select控件使用,数据格式有两种:
     * 1、一种是在初始化的时候用格式为['110100'=>'北京市'],
     *   主要在编辑页面用,通过上级的code获取到该options并渲染到select控件中。
     * 2、第二种是联动的数据,数据格式为[{"id": 110100,"text": "北京市"}],
     *   通常用着select控件在选择的时候触发的事件调用
     *
     * @param string $type 行政区域类型:province,city,district,bizdistrict
     * @param string $keyword
     * @param string $operate 当前获取数据的方法,默认是联动获取数据。如果是init说明是初始化option
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public function getSelectOptionsByKeyword($type = 'province', $keyword = '', $operate = 'ajax')
    {
        // 设置缓存保存时间
        $minutes = self::MINUTES;

        // 定义缓存key
        $cache_key = 'admin_select_options_' . $type .'_'.$operate .'_'.$keyword;

        //dump($cache_key);
        // 从 Cache 中获取
        $options = Cache::get($cache_key);
        $options = [];
        //dump($options);

        // 在缓存中获取到,直接返回
        if (is_array($options) && !empty($options)) {
            return $options;
        }

        //根据不同的类别
        $level = $this -> getLevel($type);

        $fields         = ['code', 'name','initial'];
        $orderby        = 'initial,name';
        $where['level']  = $level;
        if ($keyword) {
            $where[] = ['name','LIKE', '%'.$keyword .'%'];
        }

        $list = AdministrativeDivision::where($where)->orderByRaw($orderby)->get($fields);

        if ($list) {
            $options = [];
            foreach ($list as $key => $vo) {
                $options[$key]['id']    = $vo->code;
                $options[$key]['text']  = $vo->initial.'-'.$vo->name;
            }

            // // ajax 获取结构必须 多要给data
            // $options['data'] = $arr;
            Cache::put($cache_key, $options, $minutes);
        }

        return $options;
    }

    /**
     * 根据区域的类别获取级别
     * @param   $type
     * @return int|mixed
     */
    public function getLevel($type)
    {
        $options = AdministrativeDivision::LEVEL_OPTIONS;
        return Arr::get($options, $type, self::LEVEL_CITY);
    }
}