| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505 |
- <?php
- /**
- * 厦门云联储网络科技有限公司
- * https://www.baokuaiyun.com
- * Copyright (c) 2023 爆块云 All rights reserved.
- */
- namespace app\models;
- use Yii;
- use yii\helpers\Json;
- use yii\db\ActiveRecord;
- use yii\behaviors\TimestampBehavior;
- use yii\caching\DbDependency;
- /**
- * This is the model class for table "{{%district}}".
- *
- * @property integer $id
- * @property integer $parent_id
- * @property string $citycode
- * @property string $adcode
- * @property string $name
- * @property string $lng
- * @property string $lat
- * @property string $level
- */
- class District extends \yii\db\ActiveRecord
- {
- const IS_DELETE_YES = 1;//已删除
- const IS_DELETE_NO = 0;//未删除
- /**
- * @inheritdoc
- */
- public static function tableName()
- {
- return '{{%district}}';
- }
- public function behaviors()
- {
- return [
- [
- 'class' => TimestampBehavior::class,
- 'attributes' => [
- ActiveRecord::EVENT_BEFORE_INSERT => ['updated_at', 'created_at'],
- ActiveRecord::EVENT_BEFORE_UPDATE => 'updated_at'
- ]
- ]
- ];
- }
- /**
- * @inheritdoc
- */
- public function rules()
- {
- return [
- [['parent_id', 'is_delete'], 'integer'],
- [['citycode', 'adcode', 'name', 'lng', 'lat', 'level'], 'required'],
- [['citycode', 'adcode', 'name', 'lng', 'lat', 'level'], 'string', 'max' => 255],
- ];
- }
- /**
- * @inheritdoc
- */
- public function attributeLabels()
- {
- return [
- 'id' => 'ID',
- 'parent_id' => 'Parent ID',
- 'citycode' => 'Citycode',
- 'adcode' => 'Adcode',
- 'name' => 'Name',
- 'lng' => '经度',
- 'lat' => '纬度',
- 'level' => 'Level',
- 'is_delete' => 'IS DELETE',
- 'created_at' => 'created_at',
- 'updated_at' => 'updated_at',
- ];
- }
- public function getCity()
- {
- return $this->hasMany(District::className(), ['parent_id'=>'id'])->where(['level'=>'city']);
- }
- /**
- * 获取所有的省市区
- * @return District[]
- */
- public static function getAll()
- {
- return self::getDistrictInfoAllField();
- if (cache()->get('district_info'))
- return cache()->get('district_info');
- $province = self::find()->where(['level' => 'province'])->select(['id' ,'name', 'level'])->asArray()->all();
- foreach ($province as &$v1) {
- $v1['cityAll'] = self::find()->where(['level' => 'city', 'parent_id' => $v1['id']])
- ->select(['id','name', 'level'])->asArray()->all();
- if (is_array($v1['cityAll'])) {
- foreach ($v1['cityAll'] as &$v2) {
- $v2['districtAll'] = self::find()->where(['level' => 'district', 'parent_id' => $v2['id']])
- ->select(['id', 'name', 'level'])->asArray()->all();
- if (is_array($v2['districtAll'])) {
- foreach ($v2['districtAll'] as &$v3) {
- $v3['townAll'] = self::find()
- ->where(['level' => 'town', 'parent_id' => $v3['id']])
- ->select(['id', 'name', 'level'])
- ->asArray()
- ->all();
- if (is_array($v3['townAll'])) {
- foreach ($v3['townAll'] as &$v4) {
- $v4['villageAll'] = self::find()
- ->where(['level' => 'village', 'parent_id' => $v4['id']])
- ->select(['id', 'name', 'level'])
- ->asArray()
- ->all();
- }
- }
- }
- }
- }
- }
- }
- cache()->set('district_info', $province);
- return $province;
- }
- public static function getDistrictInfoAllField(...$args)
- {
- $childKey = 0;
- $cacheKey = array_merge(['district_info_all_field'], $args);
- if ($cacheV = cache()->get($cacheKey)) {
- return $cacheV;
- }
- $province = [];
- $city = [];
- $district = [];
- $town = [];
- $village = [];
- // 分批查询
- $query = self::find()
- ->where(['is_delete' => 0])
- ->select(['id', 'parent_id', 'name', 'level', 'lng', 'lat', 'adcode'])
- ->asArray();
- foreach ($query->batch(1000) as $rows) {
- foreach ($rows as $item) {
- switch ($item['level']) {
- case 'province':
- $province[] = $item;
- break;
- case 'city':
- $city[] = $item;
- break;
- case 'district':
- $district[] = $item;
- break;
- case 'town':
- $town[] = $item;
- break;
- case 'village':
- $village[] = $item;
- break;
- }
- }
- unset($rows);
- }
- // 按 parent_id 索引,优化循环
- $cityByParent = [];
- $districtByParent = [];
- $townByParent = [];
- $villageByParent = [];
- foreach ($city as $item) {
- $cityByParent[$item['parent_id']][] = $item;
- }
- foreach ($district as $item) {
- $districtByParent[$item['parent_id']][] = $item;
- }
- foreach ($town as $item) {
- $townByParent[$item['parent_id']][] = $item;
- }
- foreach ($village as $item) {
- $villageByParent[$item['parent_id']][] = $item;
- }
- // 构建层级结构
- foreach ($province as &$v) {
- $v['cityAll'] = $cityByParent[$v['id']] ?? [];
- foreach ($v['cityAll'] as &$i_city) {
- $i_city['districtAll'] = $districtByParent[$i_city['id']] ?? [];
- foreach ($i_city['districtAll'] as &$i_district) {
- $i_district['townAll'] = $townByParent[$i_district['id']] ?? [];
- foreach ($i_district['townAll'] as &$i_town) {
- $i_town['villageAll'] = $villageByParent[$i_town['id']] ?? [];
- }
- }
- }
- }
- // 设置缓存
- $sqlDependency = new \yii\caching\DbDependency(['sql' => self::find()->select('MAX(updated_at)')->createCommand()->getRawSql()]);
- cache()->set($cacheKey, $province, 86400 * 100, $sqlDependency);
- return $province;
- }
- public static function getAll2($childKey = 0)
- {
- ini_set('memory_limit', '1000M');
- set_time_limit(0);
- $cacheKey = array_merge(['district_info_all_field'], func_get_args());
- if ($cacheV = cache()->get($cacheKey))
- return $cacheV;
- $province = [];
- $city = [];
- $district = [];
- $town = [];
- $village = [];
- $list = self::find()->where(['is_delete' => 0])->select(['id' ,'parent_id' ,'name', 'level', 'lng', 'lat','adcode'])->asArray()->all();
- foreach($list as $item){
- if($item['level'] == 'province'){
- $province[] = $item;
- }
- if($item['level'] == 'city'){
- $city[] = $item;
- }
- if($item['level'] == 'district'){
- $district[] = $item;
- }
- if($item['level'] == 'town'){
- $town[] = $item;
- }
- if($item['level'] == 'village'){
- $village[] = $item;
- }
- }
- foreach ($province as &$v) {
- foreach($city as $d => $i_city){
- if($i_city['parent_id'] == $v['id']){
- foreach($district as $c => $i_district){
- $childKey == 0 && $i_district['townAll'] = [];
- $childKey == 1 && $i_district['children'] = [];
- if($i_district['parent_id'] == $i_city['id']){
- foreach($town as $b => $i_town){
- $childKey == 0 && $i_town['villageAll'] = [];
- $childKey == 1 && $i_town['children'] = [];
- if($i_town['parent_id'] == $i_district['id']){
- foreach($village as $a => $i_village){
- if($i_village['parent_id'] == $i_town['id']){
- $childKey == 0 && $i_town['villageAll'][] = $i_village;
- $childKey == 1 && $i_town['children'][] = $i_village;
- unset($village[$a]);
- }
- }
- $childKey == 0 && $i_district['townAll'][] = $i_town;
- $childKey == 1 && $i_district['children'][] = $i_town;
- unset($town[$b]);
- }
- }
- $childKey == 0 && $i_city['districtAll'][] = $i_district;
- $childKey == 1 && $i_city['children'][] = $i_district;
- unset($district[$c]);
- }
- }
- $childKey == 0 && $v['cityAll'][] = $i_city;
- $childKey == 1 && $v['children'][] = $i_city;
- unset($city[$d]);
- }
- }
- }
- $sqlDependency = new \yii\caching\DbDependency(['sql'=>Self::find()->select("max(updated_at)")->createCommand()->getRawSql()]);
- cache()->set($cacheKey, $province, 86400 * 100, $sqlDependency);
- return $province;
- }
- /**
- * 验证起送规则
- */
- public static function verificationOffer ($address, $price)
- {
- $offerInfo = OfferPrice::findOne(['store_id' => get_store_id(), 'is_delete' => 0]);
- if (empty($offerInfo)) {
- return true;
- }
- $detail = Json::decode($offerInfo->detail)?: [];
- foreach ($detail as $val) {
- $offerPrice = $val['offer_price'];
- foreach ($val['province_list'] as $v) {
- if ($v['id'] == $address['province_id']
- || $v['id'] == $address['city_id']
- || $v['id'] == $address['district_id']) {
- if ($price >= $offerPrice) {
- return true;
- } else {
- return [
- 'msg' => '差'.($offerPrice - $price).'元',
- 'price' => $offerPrice - $price
- ];
- }
- }
- }
- }
- if ($price >= $offerInfo->price) {
- return true;
- } else {
- return [
- 'msg' => '差'.($offerInfo->price - $price).'元',
- 'price' => $offerInfo->price - $price
- ];
- }
- }
- /**
- * 获取格式化省市数据
- * @param string $type
- * @param int $value_type
- * @return District[]
- */
- public function getFormatCity($type, $value_type)
- {
- $cache_key = 'format_dis_data_'.$type.'_'.$value_type;
- if (cache()->get($cache_key))
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => cache()->get($cache_key)
- ];
- $province = self::find()
- ->where(['is_delete' => '0','level' => 'province'])
- ->select(['id' ,'name'])
- ->asArray()->all();
- //新增统一查询快速分组
- $areaAll = self::find()->where(['is_delete' => '0'])->andWhere(['!=', 'level', 'province' ])
- ->select(['parent_id','id','name'])
- ->asArray()->all();
- $childrenAll = [];
- foreach ($areaAll as $v){
- if ($value_type == 1) {
- $v['value'] = $v['id'];
- } else {
- $v['value'] = $v['name'];
- }
- $v['label'] = $v['name'];
- $childrenAll[$v['parent_id']][] = $v;
- }
- $data = [];
- foreach ($province as $v1) {
- $tmp = [];
- if ($value_type == 1) {
- $tmp['value'] = $v1['id'];
- } else {
- $tmp['value'] = $v1['name'];
- }
- $tmp['label'] = $v1['name'];
- $tmp['children'] = [];
- $v1['cityAll'] = $childrenAll[$v1['id']] ?? [];
- foreach ($v1['cityAll'] as $v2) {
- $v2['districtAll'] = $childrenAll[$v2['id']] ?? [];
- $tmp_area = [];
- if ($type == 'area') {
- foreach ($v2['districtAll'] as $v3) {
- $tmp_1 = $v3;
- $tmp_1['children'] = $childrenAll[$v3['id']] ?? [];
- $tmp_area[] = $tmp_1;
- }
- }
- $tmp['children'][] = [
- 'value' => $value_type == 1 ? $v2['id'] : $v2['name'],
- 'label' => $v2['name'],
- 'children' => $tmp_area
- ];
- }
- $data[] = $tmp;
- }
- cache()->set($cache_key, $data);
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => $data
- ];
- }
- /**
- * User: chiyanying
- * Date: 2020/9/26
- * Time: 11:07
- * @param $city_name
- * @return mixed
- * Notes:根据城市名称获取城市id
- */
- public static function getCityId($city_name)
- {
- $city = District::find()->where(['level'=>'city'])
- ->andWhere(['like','name',$city_name])->one();
- return $city->id;
- }
- /**
- * User: chiyanying
- * Date: 2020/9/28
- * Time: 11:16
- * @param $long
- * @param $lat
- * @return mixed
- * Notes:根据经纬获取详细地址
- * 例如
- {"status":"1","info":"OK","infocode":"10000","regeocode":{"formatted_address":"\u6cb3\u5357\u7701\u6d1b\u9633\u5e02\u6d1b\u9f99\u533a\u5173\u6797\u8857\u9053\u5e7f\u5229\u8857\u5b9d\u9f99\u5e7f\u573a","addressComponent":{"country":"\u4e2d\u56fd","province":"\u6cb3\u5357\u7701","city":"\u6d1b\u9633\u5e02","citycode":"0379","district":"\u6d1b\u9f99\u533a","adcode":"410311","township":"\u5173\u6797\u8857\u9053","towncode":"410311004000","neighborhood":{"name":[],"type":[]},"building":{"name":[],"type":[]},"streetNumber":{"street":"\u5c55\u89c8\u8def","number":"27\u53f7","location":"112.465602,34.614936","direction":"\u4e1c\u5357","distance":"52.5022"},"businessAreas":{"@attributes":{"type":"list"},"businessArea":[]}}}}
- */
- public static function getAddressByLocation($long, $lat)
- {
- $url = "https://restapi.amap.com/v3/geocode/regeo?output=xml&key=48d5eef8af838b0bee145cf2eaed599d&location={$long},{$lat}&radius=1000&extensions=base&batch=false&roadlevel=0";
- $header = array(
- 'Accept: application/json',
- );
- $curl = curl_init();
- //设置抓取的url
- curl_setopt($curl, CURLOPT_URL, $url);
- //设置头文件的信息作为数据流输出
- curl_setopt($curl, CURLOPT_HEADER, 0);
- // 超时设置,以秒为单位
- curl_setopt($curl, CURLOPT_TIMEOUT, 1);
- // 超时设置,以毫秒为单位
- // curl_setopt($curl, CURLOPT_TIMEOUT_MS, 500);
- // 设置请求头
- curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
- //设置获取的信息以文件流的形式返回,而不是直接输出。
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
- //执行命令
- $data = curl_exec($curl);
- // 显示错误信息
- if (curl_error($curl)) {
- \Yii::warning('获取城市信息失败');
- } else {
- // 打印返回的内容
- curl_close($curl);
- //禁止引用外部xml实体
- libxml_disable_entity_loader(true);
- $values = json_decode(json_encode(simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
- return $values['regeocode'];
- }
- }
- /**
- * User: chiyanying
- * Date: 2020/9/28
- * Time: 11:24
- * @param string $province_name
- * @param string $city_name
- * @param string $district_name
- * Notes:根据省市区相关
- */
- public static function getDistrictByAddress($province_name='',$city_name='',$district_name=''){
- $province = District::find()->where(['level'=>'province'])
- ->andWhere(['like','name',$province_name])->asArray()->one();
- $city = District::find()->where(['level'=>'city','parent_id'=>$province['id']])
- ->andWhere(['like','name',$city_name])->asArray()->one();
- $district = District::find()->where(['level'=>'district','parent_id'=>$city['id']])
- ->andWhere(['like','name',$district_name])->asArray()->one();
- return [
- 'province'=>$province,
- 'city'=>$city,
- 'district'=>$district,
- ];
- }
- /**
- * Undocumented function
- *
- * @Author LGL 24963@qq.com
- * @DateTime 2021-03-19
- * @desc:
- * @param [type] $param
- * @return object
- */
- public static function getDistrict($param)
- {
- if (is_array($param)) {
- $id = $param['id'];
- } else {
- $id = $param;
- }
- $str = District::find()->where(['id' => $id])->select('id, name, parent_id, level')->one();
- return $str;
- }
- public static function getAdcodeById($id) {
- $model = self::findOne($id);
- if(!$model){
- return '';
- }
- return $model->adcode;
- }
- }
|