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; } }