IdentifyAddress.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <?php
  2. namespace App\Handlers;
  3. use GuzzleHttp\Client;
  4. use Illuminate\Support\Collection;
  5. use Illuminate\Support\Facades\Log;
  6. use TencentCloud\Common\Credential;
  7. use TencentCloud\Common\Profile\ClientProfile;
  8. use TencentCloud\Common\Profile\HttpProfile;
  9. use TencentCloud\Ocr\V20181119\Models\IDCardOCRRequest;
  10. use TencentCloud\Ocr\V20181119\OcrClient;
  11. class IdentifyAddress {
  12. /**
  13. * Function:识别地址
  14. * Author:cyw0413
  15. */
  16. public function getDiscern($discernDel)
  17. {
  18. if (empty($discernDel)) {
  19. throw new \Exception("请传入要识别的地址");
  20. }
  21. $discernDel_left = explode ('[', $discernDel);
  22. if (!isset($discernDel_left[1])) {
  23. throw new \Exception("你填写的地址规则错误,手机号码应该用[]");
  24. }
  25. $discernDel_right = explode (']', $discernDel_left[1]);
  26. if (!isset($discernDel_right[1]) || empty($discernDel_right[1])) {
  27. throw new \Exception("你填写的地址规则错误,手机号码应该用[]");
  28. }
  29. $name = $discernDel_left[0];
  30. if (empty($name)) {
  31. throw new \Exception("你填写的姓名有误!");
  32. }
  33. $mobile = $discernDel_right[0];
  34. if (empty($mobile) ) {//|| checkMobile($mobile) == 0
  35. throw new \Exception("你填写的手机号码格式有误!");
  36. }
  37. $address = trim ($discernDel_right[1]);
  38. if (empty($address)) {
  39. throw new \Exception("你填写的地址不能为空");
  40. }
  41. $var_address = $this->getAddressArrar($address);
  42. $var_address['name'] = $name;
  43. $var_address['mobile'] = $mobile;
  44. return $var_address;
  45. }
  46. /**
  47. * Function:地址的处理
  48. * Author:cyw0413
  49. * @param $address
  50. * @return array
  51. * @throws \Exception
  52. */
  53. function getAddressArrar($address){
  54. // 获取所有地址递归列表
  55. $regions = $this->getRegions();
  56. // 初始化数据
  57. $province = $city = $district = [];
  58. // 先查找省份-第一级地区
  59. $province = $this->checkAddress($address, $regions);
  60. if($province){
  61. $province_arr = ['110000','300000','404100','310000']; //4个市辖区如果地址不存在二级(市辖区,县),则特殊处理
  62. if(!isset($province['region_code'])){
  63. throw new \Exception("请正确填写省份(市辖区)");
  64. }
  65. // 查找城市-第二级地区
  66. $city = $this->checkAddress($address, $province['list']);
  67. //这里只处理4个市辖区,可能还有多种情况,待发现
  68. if(in_array($province['region_code'],$province_arr) && count($city['list']) == 0){
  69. $city = $this->checkAddress('市辖区', $province['list']);
  70. if($city){
  71. // 查找地区-第三级地区
  72. $district = $this->checkAddress($address, $city['list']);
  73. //如果没有找到,则查找另外一个二级地区
  74. if(!isset($district['region_code'])){
  75. $city = $this->checkAddress('县', $province['list']);
  76. // 查找地区-第三级地区
  77. $district = $this->checkAddress($address, $city['list']);
  78. }
  79. }
  80. }else{
  81. if($city){
  82. // 查找地区-第三级地区
  83. $district = $this->checkAddress($address, $city['list']);
  84. }
  85. }
  86. }else{
  87. //省份不填,报错误
  88. throw new \Exception("省份没填写,请检查");
  89. }
  90. return $this->getAddressInfo($address, $province, $city, $district);
  91. }
  92. /**
  93. * 匹配正确的城市地址
  94. * @param $address
  95. * @param $city_list
  96. * @param int $force
  97. * @param int $str_len
  98. * @return array
  99. **/
  100. function checkAddress($address, $city_list, $force=false, $str_len=2){
  101. $num = 0;
  102. $list = array();
  103. $result = array();
  104. // 遍历所有可能存在的城市
  105. foreach ($city_list as $city_key=>$city){
  106. $city_name = mb_substr($city['region_name'], 0, $str_len,'utf-8');
  107. // 判断是否存包含当前地址字符
  108. $city_arr = explode($city_name, $address);
  109. // 如果存在相关字眼,保存该地址的所有子地址
  110. if(count($city_arr) >= 2){
  111. // 必须名称长度同时达到当前比对长度
  112. if(strlen($city['region_name']) < $str_len){
  113. continue;
  114. }
  115. $num ++;
  116. if(isset($city['child'])){
  117. $list = $list + $city['child'];
  118. }
  119. $result[] = array(
  120. 'region_code' => $city_key,
  121. 'region_name' => $city['region_name'],
  122. 'list' =>$list,
  123. );
  124. }
  125. }
  126. // 如果有多个存在,则加大字符匹配长度
  127. if($num > 1 || $force){
  128. $region_name1 = $result[0]['region_name'];
  129. $region_name2 = $result[1]['region_name'];
  130. if(strlen($region_name1) == strlen($region_name2) && strlen($region_name1) == $str_len){
  131. $region_id1 = $result[0]['region_code'];
  132. $region_id2 = $result[1]['region_code'];
  133. $index = $region_id1 > $region_id2 ? 1 : 0;
  134. $result = $result[$index];
  135. return $result;
  136. }
  137. return $this->checkAddress($address, $city_list, $force, $str_len+1);
  138. } else {
  139. $result[0]['list'] = $list;
  140. return $result[0];
  141. }
  142. }
  143. /**
  144. * 根据原地址返回详细信息
  145. * @param $address
  146. * @param $province
  147. * @param $city
  148. * @param $area
  149. * @return array
  150. **/
  151. function getAddressInfo($address, $province, $city, $district){
  152. // 查找最后出现的地址 - 截取详细信息
  153. if(!isset($province['region_name'])){
  154. throw new \Exception("请检查并正确填写省份(市辖区)");
  155. }
  156. if(!isset($city['region_name'])){
  157. throw new \Exception("请检查并正确填写城市");
  158. }
  159. if(!isset($district['region_name'])){
  160. throw new \Exception("请检查并正确填写区域(县/区/镇)");
  161. }
  162. $find_str = '';
  163. if($province['region_name']){
  164. $find_str = $province['region_name'];
  165. if($city['region_name']){
  166. $find_str = $city['region_name'];
  167. if(isset($district['region_name']) && $district['region_name']){
  168. $find_str = $district['region_name'];
  169. }
  170. }
  171. }
  172. // 截取详细的信息
  173. $find_str_len = mb_strlen($find_str,'utf-8');
  174. for($i=0; $i<$find_str_len-1; $i++){
  175. $substr = mb_substr($find_str,0,$find_str_len - $i, 'utf-8');
  176. $end_index = mb_strpos($address, $substr);
  177. if ($end_index){
  178. $address = mb_substr($address, $end_index + mb_strlen($substr) , mb_strlen($address) - $end_index);
  179. }
  180. }
  181. !empty($find_str) && $find_str = '|\S*' . $find_str;
  182. $area['info'] = preg_replace("/\s*|,|,|:|:{$find_str}/i", '', $address);
  183. if(empty($area['info'])){
  184. throw new \Exception("详细地址不存在,请检查");
  185. }
  186. return $address = [
  187. 'province' => $province['region_code'],
  188. 'city' => $city['region_code'],
  189. 'district' => $district['region_code'],
  190. 'info' => $area['info']
  191. ];
  192. }
  193. }