文章来自:php自学中心
作者:磊丰
地址自动识别现在普遍,特别是用在快递填写地址,姓名,手机号码的时候,会把这些按照一定的规范填写后,点击自动识别后,会自动填写到各自的input。最近也简单的实现了这个功能,给后台添加用户的时候,自动识别地址。下面咱们来看看具体实现。
代码实现
controller,这里首先注入服务容器,在构造函数里注入。
/** @var UserRepository */ private $userRepository; public function __construct(UsersRepository $userRepo) { $this->userRepository = $userRepo; } /** * Function:地址识别 * Author:cyw0413 * @param Request $request * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response| * \Laravel\Lumen\Http\ResponseFactory|\Symfony\Component\HttpFoundation\Response */ public function getDiscern(Request $request) { $discernDel = $request->input('discernDel'); try{ DB::beginTransaction(); $ address = $this->userRepository->getDiscern($discernDel); DB::commit(); }catch (\ Exception $e){ DB::rollBack(); $msg = "信息提示:".$e->getMessage().",行:".$e->getLine(); return response(['code' => 0, 'msg'=>$msg]); } return response(['code'=>1,'msg'=>$address]); //地址识别完成 }
userRepository容器,用来处理地址识别的各种业务代码
/** * Function:识别地址 * Author:cyw0413 */ public function getDiscern($discernDel) { if (empty($discernDel)) { throw new \Exception("请传入要识别的地址"); } $discernDel_left = explode ('[', $discernDel); if (!isset($discernDel_left[1])) { throw new \Exception("你填写的地址规则错误,手机号码应该用[]"); } $discernDel_right = explode (']', $discernDel_left[1]); if (!isset($discernDel_right[1]) || empty($discernDel_right[1])) { throw new \Exception("你填写的地址规则错误,手机号码应该用[]"); } $name = $discernDel_left[0]; if (empty($name)) { throw new \Exception("你填写的姓名有误!"); } $ mobile = $discernDel_right[0]; if (empty($mobile) || checkMobile($mobile) == 0) { throw new \Exception("你填写的手机号码格式有误!"); } $address = trim ($discernDel_right[1]); if (empty($address)) { throw new \Exception("你填写的地址不能为空"); } $var_address = $this->getAddressArrar($address); $var_address['name'] = $name; $var_address['mobile'] = $mobile; return $var_address; } /** * Function:地址的处理 * Author:cyw0413 * @param $address * @return array * @throws \Exception */ function getAddressArrar($address){ // 获取所有地址递归列表 $regions = $this->getRegions(); // 初始化数据 $province = $city = $district = []; // 先查找省份-第一级地区 $province = $this->checkAddress($address, $regions); if($province){ $province_arr = ['110000','300000','404100','310000']; //4个 市辖区 如果地址不存在二级(市辖区,县),则特殊处理 if(!isset($province['region_code'])){ throw new \Exception("请正确填写省份(市辖区)"); } // 查找城市-第二级地区 $city = $this->checkAddress($address, $province['list']); //这里只处理4个市辖区,可能还有多种情况,待发现 if(in_array($province['region_code'],$province_arr) && count($city['list']) == 0){ $city = $this->checkAddress('市辖区', $province['list']); if($city){ // 查找地区-第三级地区 $district = $this->checkAddress($address, $city['list']); //如果没有找到,则查找另外一个二级地区 if(!isset($district['region_code'])){ $city = $this->checkAddress('县', $province['list']); // 查找地区-第三级地区 $district = $this->checkAddress($address, $city['list']); } } }else{ if($city){ // 查找地区-第三级地区 $district = $this->checkAddress($address, $city['list']); } } }else{ //省份不填,报错误 throw new \Exception("省份没填写,请检查"); } return $this->getAddressInfo($address, $province, $city, $district); } /** * 匹配正确的城市地址 * @param $address * @param $city_list * @param int $ force * @param int $str_len * @return array **/ function checkAddress($address, $city_list, $force=false, $str_len=2){ $num = 0; $list = array(); $result = array(); // 遍历所有可能存在的城市 foreach ($city_list as $city_key=>$city){ $city_name = mb_substr($city['region_name'], 0, $str_len,'utf-8'); // 判断是否存包含当前地址字符 $city_arr = explode($city_name, $address); // 如果存在相关字眼,保存该地址的所有子地址 if(count($city_arr) >= 2){ // 必须名称长度同时达到当前比对长度 if( strlen ($city['region_name']) < $str_len){ continue; } $num ++; if(isset($city['child'])){ $list = $list + $city['child']; } $result[] = array( 'region_code' => $city_key, 'region_name' => $city['region_name'], 'list' =>$list, ); } } // 如果有多个存在,则加大字符匹配长度 if($num > 1 || $force){ $region_name1 = $result[0]['region_name']; $region_name2 = $result[1]['region_name']; if(strlen($region_name1) == strlen($region_name2) && strlen($region_name1) == $str_len){ $region_id1 = $result[0]['region_code']; $region_id2 = $result[1]['region_code']; $index = $region_id1 > $region_id2 ? 1 : 0; $result = $result[$index]; return $result; } return $this->checkAddress($address, $city_list, $force, $str_len+1); } else { $result[0]['list'] = $list; return $result[0]; } } /** * 根据原地址返回详细信息 * @param $address * @param $province * @param $city * @param $area * @return array **/ function getAddressInfo($address, $province, $city, $district){ // 查找最后出现的地址 - 截取详细信息 if(!isset($province['region_name'])){ throw new \Exception("请检查并正确填写省份(市辖区)"); } if(!isset($city['region_name'])){ throw new \Exception("请检查并正确填写城市"); } if(!isset($district['region_name'])){ throw new \Exception("请检查并正确填写区域(县/区/镇)"); } $find_str = ''; if($province['region_name']){ $find_str = $province['region_name']; if($city['region_name']){ $find_str = $city['region_name']; if(isset($district['region_name']) && $district['region_name']){ $find_str = $district['region_name']; } } } // 截取详细的信息 $find_str_len = mb_strlen($find_str,'utf-8'); for($i=0; $i<$find_str_len-1; $i++){ $substr = mb_substr($find_str,0,$find_str_len - $i, 'utf-8'); $end_index = mb_strpos($address, $substr); if ($end_index){ $address = mb_substr($address, $end_index + mb_strlen($substr) , mb_strlen($address) - $end_index); } } !empty($find_str) && $find_str = '|\S*' . $find_str; $area['info'] = preg_replace("/\s*|,|,|:|:{$find_str}/i", '', $address); if(empty($area['info'])){ throw new \Exception("详细地址不存在,请检查"); } return $address = [ 'province' => $province['region_code'], 'city' => $city['region_code'], 'district' => $district['region_code'], 'info' => $area['info'] ]; }
前端html代码
{!! Form::label('discern', '自动识别地址:',['class' => 'control-label col-sm-2']) !!}{!! Form::textarea('discern', '', ['class' => 'form-textarea form-control form-discern','rows' => 3]) !!}*查看模板
jquery代码都有。。
/** * 地址识别 * @returns {boolean} */ function getDiscern(){ var discernDel = $(".form-discern").val(); if(!discernDel){ alert("请输入要识别的地址"); return false; } $.ajax({ type: 'POST', url: "{!! route('admin.user.getDiscern') !!}", data: { '_token': csrf_token(), 'discernDel': discernDel }, dataType: 'json', timeout: 50000, success: function (res) { if (res.code == 1) { $("input[name='addr[linkman]']").val(res.msg.name); $("input[name='user_name']").val(res.msg.mobile); $("input[name='addr[address]']").val(res.msg.info); //触发 change 事件 $('#province').val(res.msg.province). trigger ('change'); $('#city').val(res.msg.city).trigger('change'); $('#area').val(res.msg.district).trigger('change'); //识别后清除 $(".form-discern").val(""); } else { alert(res.msg); } } }) }
代码可以帮你实现你想要的,不妨一试
感谢阅读
海报
0 条评论
169
相关文章
本站已关闭游客评论,请登录或者注册后再评论吧~