CustomerWriteReport.php 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Model\AreaMap;
  4. use App\Model\BasicType;
  5. use App\Model\BasicTypeAllUse;
  6. use App\Model\Customer;
  7. use App\Model\CustomerInfo;
  8. use App\Model\CustomerReport;
  9. use App\Model\CustomerReportDepart;
  10. use App\Model\FollowUpRecord;
  11. use App\Model\SalesOrder;
  12. use App\Model\SeeRange;
  13. use Illuminate\Console\Command;
  14. use Illuminate\Support\Facades\DB;
  15. class CustomerWriteReport extends Command
  16. {
  17. /**
  18. * The name and signature of the console command.
  19. *
  20. * @var string
  21. */
  22. protected $signature = 'command:customer_write_report';
  23. /**
  24. * The console command description.
  25. *
  26. * @var string
  27. */
  28. protected $description = 'Command description';
  29. /**
  30. * Create a new command instance.
  31. *
  32. * @return void
  33. */
  34. public function __construct()
  35. {
  36. parent::__construct();
  37. }
  38. /**
  39. * Execute the console command.
  40. *
  41. * @return mixed
  42. */
  43. public function handle()
  44. {
  45. echo "执行任务--------start---------------\n";
  46. try {
  47. $this->customerWrite();
  48. }catch (\Throwable $exception){
  49. echo "发生异常:" . $exception->getFile() . "|" . $exception->getMessage() . "|" . $exception->getLine() . "\n";
  50. }
  51. echo "执行任务--------end---------------\n";
  52. }
  53. private function customerWrite(){
  54. //今天到上月今天的时间戳
  55. $nowStamp = time();
  56. $lastMonth = date("Y-m-d 00:00:00", strtotime("-1 month"));
  57. $lastMonthStamp = strtotime($lastMonth);
  58. list($provinceMap, $cityMap, $countyMap) = $this->constructAddress();
  59. // dd($provinceMap, $cityMap, $countyMap);
  60. // dd(count($provinceMap), count($cityMap), count($countyMap));
  61. // $this->forInsertArea($provinceMap, $cityMap, $countyMap);dd(122);
  62. Customer::where("del_time",0)
  63. ->where('enter_time','>=', $lastMonthStamp)
  64. ->where('enter_time','<=', $nowStamp)
  65. ->orderBy('id')
  66. ->select('id','title','model_type','consulting_product_new','enter_time','address2','top_depart_id','customer_from','car_type')
  67. ->chunkById(200, function ($data) use($provinceMap, $cityMap, $countyMap,$nowStamp){
  68. // 开启事务
  69. DB::transaction(function () use ($data, $provinceMap, $cityMap, $countyMap, $nowStamp) {
  70. $dataArray = $data->toArray();
  71. foreach ($dataArray as $key => $value){
  72. $dataArray[$key]['customer_id'] = $value['id'];
  73. unset($dataArray[$key]['id']);
  74. }
  75. list($main, $main_depart) = $this->processingData($dataArray, $provinceMap, $cityMap, $countyMap, $nowStamp);
  76. if (! empty($main)) {
  77. $customer_ids = array_column($dataArray, 'customer_id');
  78. // 删除旧数据
  79. CustomerReport::where('del_time', 0)
  80. ->whereIn('customer_id', $customer_ids)
  81. ->update(['del_time' => $nowStamp]);
  82. CustomerReportDepart::where('del_time', 0)
  83. ->whereIn('customer_id', $customer_ids)
  84. ->update(['del_time' => $nowStamp]);
  85. // 写入新数据
  86. CustomerReport::insert($main);
  87. CustomerReportDepart::insert($main_depart);
  88. echo '200条写入中' . PHP_EOL;
  89. } else {
  90. echo '暂无数据写入' . PHP_EOL;
  91. }
  92. });
  93. });
  94. }
  95. private function processingData($data,$provinceMap,$cityMap,$countyMap,$time){
  96. $return = [];
  97. $customer_id = array_column($data,'customer_id');
  98. $range = SeeRange::where('del_time',0)
  99. ->whereIn('data_id', $customer_id)
  100. ->where('data_type',SeeRange::type_one)
  101. ->where('type',SeeRange::data_three)
  102. ->select('data_id as customer_id','param_id as top_depart_id')
  103. ->get()->toArray();
  104. $map = [];
  105. foreach ($range as $value){
  106. $map[$value['customer_id']][] = $value['top_depart_id'];
  107. }
  108. $isset_map = SalesOrder::where('del_time', 0)
  109. ->whereIn('customer_id', $customer_id)
  110. ->pluck('customer_id')
  111. ->unique()
  112. ->flip()
  113. ->map(fn() => 1)
  114. ->toArray();
  115. // 最新的跟进记录
  116. $latestRecordsArray = $detail_insert = [];
  117. $latestRecords = FollowUpRecord::whereIn('data_id', $customer_id)
  118. ->where('type', FollowUpRecord::type_one)
  119. ->where('del_time',0)
  120. ->select('data_id','follow_type','crt_id')
  121. ->orderBy('id','desc')
  122. ->get()->toArray();
  123. foreach ($latestRecords as $value){
  124. if(! isset($latestRecordsArray[$value['data_id']])){
  125. $latestRecordsArray[$value['data_id']] = [
  126. 'follow_type' => $value['follow_type'],
  127. 'num' => 1,
  128. ];
  129. }else{
  130. $latestRecordsArray[$value['data_id']]['num'] += 1;
  131. }
  132. $detail_insert[] = [
  133. 'customer_id' => $value['data_id'],
  134. 'top_depart_id' => 0,
  135. 'crt_time' => $time,
  136. 'type' => CustomerReportDepart::type_three,
  137. 'man_id' => $value['crt_id'],
  138. ];
  139. }
  140. $customer_info = CustomerInfo::where('del_time',0)
  141. ->whereIn('customer_id',$customer_id)
  142. ->whereIn('type',[CustomerInfo::type_one, CustomerInfo::type_two])
  143. ->select('type','contact_type','contact_info','customer_id','data_id')
  144. ->get()->toArray();
  145. $customer_info_map = $customer_info_map2 = [];
  146. foreach ($customer_info as $value){
  147. if($value['type'] == CustomerInfo::type_one){
  148. if(! $value['contact_info']) continue;
  149. if(! empty($customer_info_map[$value['customer_id']])) continue;
  150. $customer_info_map[$value['customer_id']] = $value['contact_info'];
  151. }else{
  152. if(! $value['data_id']) continue;
  153. if(! empty($customer_info_map2[$value['customer_id']]) && in_array($value['data_id'], $customer_info_map2[$value['customer_id']])) continue;
  154. $customer_info_map2[$value['customer_id']][] = $value['data_id'];
  155. }
  156. }
  157. $array = array_unique(array_merge_recursive(array_column($data,'customer_from'),array_column($data,'car_type')));
  158. $basic_map = BasicType::whereIn('id',$array)
  159. ->pluck('title','id')
  160. ->toArray();
  161. $basic_all_map = BasicTypeAllUse::where('type', BasicTypeAllUse::type_one)
  162. ->whereIn('id',array_unique(array_column($data,'consulting_product_new')))
  163. ->pluck('title','id')
  164. ->toArray();
  165. foreach ($data as $key => $value){
  166. $province = $province_code = $city = $city_code = "";
  167. $is_success = 0;
  168. if(! empty($value['address2'])){
  169. $tmp = $this->parseAddress($value['address2'], $provinceMap, $cityMap,$countyMap);
  170. if(empty($tmp['province']['label']) || empty($tmp['city']['label'])){
  171. // $tmp['origin'] = $value['address2'];
  172. // $a = [
  173. // "provice" => $tmp['province']['label'],
  174. // "provice_code" => $tmp['province']['value'],
  175. // "city" => $tmp['city']['label'],
  176. // "city_code" => $tmp['city']['value'],
  177. // "origin" => $value['address2']
  178. // ];
  179. // $return[] = $a;
  180. }else{
  181. $province = $tmp['province']['label'];
  182. $province_code = $tmp['province']['value'];
  183. $city = $tmp['city']['label'];
  184. $city_code = $tmp['city']['value'];
  185. $is_success = 1;
  186. }
  187. }
  188. $data[$key]['province'] = $province;
  189. $data[$key]['province_code'] = $province_code;
  190. $data[$key]['city'] = $city;
  191. $data[$key]['city_code'] = $city_code;
  192. $data[$key]['is_success'] = $is_success;
  193. $belong_depart_id = [$value['top_depart_id']];
  194. if(isset($map[$value['customer_id']])) $belong_depart_id = array_unique($map[$value['customer_id']]);
  195. foreach ($belong_depart_id as $b){
  196. $detail_insert[] = [
  197. 'customer_id' => $value['customer_id'],
  198. 'top_depart_id' => $b,
  199. 'crt_time' => $time,
  200. 'type' => CustomerReportDepart::type_one,
  201. 'man_id' => 0,
  202. ];
  203. }
  204. $customer_info2 = $customer_info_map2[$value['customer_id']] ?? [];
  205. if(! empty($customer_info2)){
  206. foreach ($customer_info2 as $v_i){
  207. $detail_insert[] = [
  208. 'customer_id' => $value['customer_id'],
  209. 'top_depart_id' => 0,
  210. 'crt_time' => $time,
  211. 'type' => CustomerReportDepart::type_two,
  212. 'man_id' => $v_i,
  213. ];
  214. }
  215. }
  216. $type = -1;
  217. $r_array = $latestRecordsArray[$value['customer_id']] ?? [];
  218. $num = $r_array['num'] ?? 0;
  219. if(isset($isset_map[$value['customer_id']])){
  220. $type = 3;
  221. }else{
  222. if(! empty($r_array)) $type = $r_array['follow_type'];
  223. }
  224. $data[$key]['type'] = $type;
  225. $data[$key]['follow_num'] = $num;
  226. $data[$key]['contact_info'] = $customer_info_map[$value['customer_id']] ?? "";
  227. $data[$key]['customer_from'] = $basic_map[$value['customer_from']] ?? "";
  228. $data[$key]['car_type'] = $customer_info_map[$value['car_type']] ?? "";
  229. $data[$key]['consulting_product_new_title'] = $basic_all_map[$value['consulting_product_new']] ?? "";
  230. $data[$key]['crt_time'] = $time;
  231. }
  232. return [$data, $detail_insert];
  233. }
  234. private function forInsertArea($provinceMap, $cityMap, $countyMap){
  235. $insert = [];
  236. foreach ($provinceMap as $key => $value){
  237. $insert[] = [
  238. 'key' => $key,
  239. 'label' => $value['label'],
  240. 'value' => $value['value'],
  241. 'province' => "",
  242. 'type' => 1,
  243. ];
  244. }
  245. foreach ($cityMap as $key => $value){
  246. $insert[] = [
  247. 'key' => $key,
  248. 'label' => $value['label'],
  249. 'value' => $value['value'],
  250. 'province' => $value['province'],
  251. 'type' => 2,
  252. ];
  253. }
  254. foreach ($countyMap as $key => $value){
  255. $insert[] = [
  256. 'key' => $key,
  257. 'label' => $value['city_label'],
  258. 'value' => $value['city_value'],
  259. 'province' => $value['province_value'],
  260. 'type' => 3,
  261. ];
  262. }
  263. AreaMap::where('del_time',0)
  264. ->where('is_create_by_human',0)
  265. ->update(['del_time' => time()]);
  266. AreaMap::insert($insert);
  267. }
  268. private function constructAddress($type = 0) {
  269. if(! empty($type)){
  270. $result = AreaMap::where('del_time',0)
  271. ->select('key','label','value','province','type')
  272. ->get()->toArray();
  273. $provinceMap = [];
  274. $cityMap = [];
  275. $countyMap = []; // 新增区县映射表
  276. foreach ($result as $value){
  277. if($value['type'] == 1){
  278. $provinceMap[$value['key']] = [
  279. 'label' => $value['label'],
  280. 'value' => $value['value'],
  281. ];
  282. }elseif($value['type'] == 2){
  283. $cityMap[$value['key']] = [
  284. 'label' => $value['label'],
  285. 'value' => $value['value'],
  286. 'province' => $value['province'],
  287. ];
  288. }else{
  289. $countyMap[$value['key']] = [
  290. 'city_label' => $value['label'],
  291. 'city_value' => $value['value'],
  292. 'province_value' => $value['value'],
  293. 'type' => 3,
  294. ];
  295. }
  296. }
  297. }else{
  298. $addressData = config('address3');
  299. if(is_string($addressData)) $addressData = json_decode($addressData, true);
  300. $provinceMap = [];
  301. $cityMap = [];
  302. $countyMap = []; // 新增区县映射表
  303. // 添加直辖市特殊处理
  304. $municipalities = [
  305. '110000' => ['北京', '北京市'],
  306. '120000' => ['天津', '天津市'],
  307. '310000' => ['上海', '上海市'],
  308. '500000' => ['重庆', '重庆市']
  309. ];
  310. // 添加省级简称映射
  311. $provinceAbbr = [
  312. '内蒙古' => '内蒙古自治区',
  313. '新疆' => '新疆维吾尔自治区',
  314. '广西' => '广西壮族自治区',
  315. '宁夏' => '宁夏回族自治区',
  316. '西藏' => '西藏自治区',
  317. ];
  318. foreach ($addressData as $province) {
  319. $pValue = $province['value'];
  320. $pLabel = $province['label'];
  321. // 添加省份全称和简称
  322. $shortProvince = preg_replace('/(省|市|自治区|特别行政区)$/u', '', $pLabel);
  323. $provinceMap[$pLabel] = ['label' => $pLabel, 'value' => $pValue];
  324. $provinceMap[$shortProvince] = ['label' => $pLabel, 'value' => $pValue];
  325. $provinceMap[$pValue] = ['label' => $pLabel, 'value' => $pValue]; // 新增:通过编码直接访问
  326. // 添加省级简称
  327. if (isset($provinceAbbr[$shortProvince])) {
  328. $provinceMap[$shortProvince] = ['label' => $pLabel, 'value' => $pValue];
  329. }
  330. // 处理直辖市
  331. if (isset($municipalities[$pValue])) {
  332. $cityLabel = $municipalities[$pValue][1];
  333. $cityMap[$cityLabel] = $cityMap[$municipalities[$pValue][0]] = [
  334. 'label' => $cityLabel,
  335. 'value' => $pValue,
  336. 'province' => $pValue
  337. ];
  338. // 添加直辖市区县映射
  339. foreach ($province['children'][0]['children'] as $district) {
  340. $dLabel = $district['label'];
  341. $countyMap[$dLabel] = [
  342. 'city_label' => $cityLabel,
  343. 'city_value' => $pValue,
  344. 'province_value' => $pValue
  345. ];
  346. // 添加区县简称(去掉"区"字)
  347. $shortDistrict = preg_replace('/区$/', '', $dLabel);
  348. if ($shortDistrict !== $dLabel) {
  349. $countyMap[$shortDistrict] = $countyMap[$dLabel];
  350. }
  351. }
  352. continue;
  353. }
  354. // 处理普通城市和区县
  355. foreach ($province['children'] as $city) {
  356. $cValue = $city['value'];
  357. $cLabel = $city['label'];
  358. // 添加城市全称和简称
  359. $shortCity = preg_replace('/(市|地区|盟)$/u', '', $cLabel);
  360. $cityMap[$cLabel] = [
  361. 'label' => $cLabel,
  362. 'value' => $cValue,
  363. 'province' => $pValue
  364. ];
  365. $cityMap[$shortCity] = [
  366. 'label' => $cLabel,
  367. 'value' => $cValue,
  368. 'province' => $pValue
  369. ];
  370. // 添加自治州特殊处理(如恩施)
  371. $specialMapping = [
  372. '延边朝鲜族自治州' => '延边',
  373. '恩施土家族苗族自治州' => '恩施',
  374. '湘西土家族苗族自治州' => '湘西',
  375. '阿坝藏族羌族自治州' => '阿坝',
  376. '凉山彝族自治州' => '凉山',
  377. '甘孜藏族自治州' => '甘孜',
  378. '黔东南苗族侗族自治州' => '黔东南',
  379. '黔南布依族苗族自治州' => '黔南',
  380. '黔西南布依族苗族自治州' => '黔西南',
  381. '楚雄彝族自治州' => '楚雄',
  382. '红河哈尼族彝族自治州' => '红河',
  383. '文山壮族苗族自治州' => '文山',
  384. '西双版纳傣族自治州' => '西双版纳',
  385. '大理白族自治州' => '大理',
  386. '德宏傣族景颇族自治州' => '德宏',
  387. '怒江傈僳族自治州' => '怒江',
  388. '迪庆藏族自治州' => '迪庆',
  389. '临夏回族自治州' => '临夏',
  390. '甘南藏族自治州' => '甘南',
  391. '海南藏族自治州' => '海南',
  392. '海北藏族自治州' => '海北',
  393. '海西蒙古族藏族自治州' => '海西',
  394. '黄南藏族自治州' => '黄南',
  395. '果洛藏族自治州' => '果洛',
  396. '玉树藏族自治州' => '玉树',
  397. '伊犁哈萨克自治州' => '伊犁',
  398. '博尔塔拉蒙古自治州' => '博尔塔拉',
  399. '昌吉回族自治州' => '昌吉',
  400. // '巴音郭楞蒙古自治州' => '巴州',
  401. '巴音郭楞蒙古自治州' => '巴音郭楞',
  402. '克孜勒苏柯尔克孜自治州' => '克孜勒苏',
  403. ];
  404. // $specialMapping = array_flip($specialMapping);
  405. if (isset($specialMapping[$shortCity])) {
  406. $cityMap[$specialMapping[$shortCity]] = [
  407. 'label' => $shortCity,
  408. 'value' => $cValue,
  409. 'province' => $pValue
  410. ];
  411. }
  412. // if (strpos($cLabel, '自治州') !== false) {
  413. //// dump($province['children']);
  414. // $autonomousShort = str_replace(['自治州', '土家族', '苗族', '壮族'], '', $cLabel);
  415. // $cityMap[$autonomousShort] = [
  416. // 'label' => $cLabel,
  417. // 'value' => $cValue,
  418. // 'province' => $pValue
  419. // ];
  420. // }
  421. // 添加城市常见简称(特殊处理)
  422. $specialAbbr = [
  423. '成都' => '成都市',
  424. '杭州' => '杭州市',
  425. '广州' => '广州市',
  426. '深圳' => '深圳市',
  427. '武汉' => '武汉市',
  428. '南京' => '南京市',
  429. '苏州' => '苏州市',
  430. '宁波' => '宁波市',
  431. '青岛' => '青岛市',
  432. ];
  433. if (isset($specialAbbr[$shortCity])) {
  434. $cityMap[$shortCity] = [
  435. 'label' => $specialAbbr[$shortCity],
  436. 'value' => $cValue,
  437. 'province' => $pValue
  438. ];
  439. }
  440. // 添加区县映射
  441. if (isset($city['children'])) {
  442. foreach ($city['children'] as $county) {
  443. $countyLabel = $county['label'];
  444. $countyMap[$countyLabel] = [
  445. 'city_label' => $cLabel,
  446. 'city_value' => $cValue,
  447. 'province_value' => $pValue
  448. ];
  449. // 添加区县简称(去掉"区"/"县"字)
  450. $shortCounty = preg_replace('/(区|县|市|自治县|黎族自治县|黎族苗族自治县)$/u', '', $countyLabel);
  451. if ($shortCounty !== $countyLabel) {
  452. $countyMap[$shortCounty] = $countyMap[$countyLabel];
  453. }
  454. }
  455. }
  456. }
  457. }
  458. }
  459. //dd($cityMap);
  460. return [$provinceMap, $cityMap, $countyMap]; // 返回三个映射表
  461. }
  462. function parseAddress($str, $provinceMap, $cityMap, $countyMap) {
  463. static $cache = [];
  464. if (isset($cache[$str])) return $cache[$str];
  465. $str = str_replace(['·', ' ', '-', '-'], '', trim($str));
  466. // 0. 处理空字符串
  467. if (empty($str)) {
  468. $result = [
  469. 'province' => ['label' => '', 'value' => ''],
  470. 'city' => ['label' => '', 'value' => '']
  471. ];
  472. $cache[$str] = $result;
  473. return $result;
  474. }
  475. // 1. 处理直辖市简称
  476. $municipalityShort = ['京', '沪', '津', '渝'];
  477. $municipalityMap = [
  478. '京' => '北京市',
  479. '沪' => '上海市',
  480. '津' => '天津市',
  481. '渝' => '重庆市'
  482. ];
  483. if (in_array(mb_substr($str, 0, 1), $municipalityShort)) {
  484. $cityName = $municipalityMap[mb_substr($str, 0, 1)];
  485. $city = $cityMap[$cityName] ?? null;
  486. if ($city) {
  487. $provinceInfo = $provinceMap[$city['province']] ?? null;
  488. $result = [
  489. 'province' => $provinceInfo ?: ['label' => $cityName, 'value' => $city['province']],
  490. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  491. ];
  492. $cache[$str] = $result;
  493. return $result;
  494. }
  495. }
  496. // 2. 完整字符串匹配城市
  497. if (isset($cityMap[$str])) {
  498. $city = $cityMap[$str];
  499. $provinceInfo = $provinceMap[$city['province']] ?? null;
  500. $result = [
  501. 'province' => $provinceInfo ?: ['label' => '', 'value' => $city['province']],
  502. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  503. ];
  504. $cache[$str] = $result;
  505. return $result;
  506. }
  507. // 3. 匹配区县(新增)
  508. if (isset($countyMap[$str])) {
  509. $county = $countyMap[$str];
  510. $cityInfo = [
  511. 'label' => $county['city_label'],
  512. 'value' => $county['city_value']
  513. ];
  514. $provinceInfo = $provinceMap[$county['province_value']] ?? null;
  515. $result = [
  516. 'province' => $provinceInfo ?: ['label' => '', 'value' => $county['province_value']],
  517. 'city' => $cityInfo
  518. ];
  519. $cache[$str] = $result;
  520. return $result;
  521. }
  522. // 4. 优先匹配3字省份(如内蒙古)
  523. if (mb_strlen($str) >= 3) {
  524. $prefix = mb_substr($str, 0, 3);
  525. if (isset($provinceMap[$prefix])) {
  526. return $this->handleMatchedProvince($prefix, mb_substr($str, 3), $provinceMap, $cityMap, $countyMap, $cache, $str);
  527. }
  528. }
  529. // 5. 匹配2字省份
  530. if (mb_strlen($str) >= 2) {
  531. $prefix = mb_substr($str, 0, 2);
  532. if (isset($provinceMap[$prefix])) {
  533. return $this->handleMatchedProvince($prefix, mb_substr($str, 2), $provinceMap, $cityMap, $countyMap, $cache, $str);
  534. }
  535. }
  536. // 6. 城市关键词扫描(加强版)
  537. $cityKeys = array_keys($cityMap);
  538. usort($cityKeys, fn($a, $b) => mb_strlen($b) - mb_strlen($a));
  539. foreach ($cityKeys as $key) {
  540. if (mb_strpos($str, $key) !== false) {
  541. $city = $cityMap[$key];
  542. $provinceInfo = $provinceMap[$city['province']] ?? null;
  543. $result = [
  544. 'province' => $provinceInfo ?: ['label' => '', 'value' => $city['province']],
  545. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  546. ];
  547. $cache[$str] = $result;
  548. return $result;
  549. }
  550. }
  551. // 7. 区县关键词扫描(新增)
  552. $countyKeys = array_keys($countyMap);
  553. usort($countyKeys, fn($a, $b) => mb_strlen($b) - mb_strlen($a));
  554. foreach ($countyKeys as $key) {
  555. if (mb_strpos($str, $key) !== false) {
  556. $county = $countyMap[$key];
  557. $provinceInfo = $provinceMap[$county['province_value']] ?? null;
  558. $result = [
  559. 'province' => $provinceInfo ?: ['label' => '', 'value' => $county['province_value']],
  560. 'city' => ['label' => $county['city_label'], 'value' => $county['city_value']]
  561. ];
  562. $cache[$str] = $result;
  563. return $result;
  564. }
  565. }
  566. // 8. 最终匹配失败
  567. $result = [
  568. 'province' => ['label' => '', 'value' => ''],
  569. 'city' => ['label' => '', 'value' => '']
  570. ];
  571. $cache[$str] = $result;
  572. return $result;
  573. }
  574. // 优化省份匹配后的处理
  575. function handleMatchedProvince($provinceKey, $remainder, $provinceMap, $cityMap, $countyMap, &$cache, $originalStr) {
  576. $province = $provinceMap[$provinceKey];
  577. // 0. 处理空余部分
  578. if (empty($remainder)) {
  579. $result = [
  580. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  581. 'city' => ['label' => '', 'value' => '']
  582. ];
  583. $cache[$originalStr] = $result;
  584. return $result;
  585. }
  586. // 1. 尝试完整匹配城市
  587. if (isset($cityMap[$remainder])) {
  588. $city = $cityMap[$remainder];
  589. $result = [
  590. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  591. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  592. ];
  593. $cache[$originalStr] = $result;
  594. return $result;
  595. }
  596. // 2. 尝试匹配区县(新增)
  597. if (isset($countyMap[$remainder])) {
  598. $county = $countyMap[$remainder];
  599. $result = [
  600. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  601. 'city' => ['label' => $county['city_label'], 'value' => $county['city_value']]
  602. ];
  603. $cache[$originalStr] = $result;
  604. return $result;
  605. }
  606. // 3. 城市关键词扫描
  607. $cityKeys = array_keys($cityMap);
  608. usort($cityKeys, fn($a, $b) => mb_strlen($b) - mb_strlen($a));
  609. foreach ($cityKeys as $key) {
  610. if (mb_strpos($remainder, $key) !== false) {
  611. $city = $cityMap[$key];
  612. $result = [
  613. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  614. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  615. ];
  616. $cache[$originalStr] = $result;
  617. return $result;
  618. }
  619. }
  620. // 4. 区县关键词扫描(新增)
  621. $countyKeys = array_keys($countyMap);
  622. usort($countyKeys, fn($a, $b) => mb_strlen($b) - mb_strlen($a));
  623. foreach ($countyKeys as $key) {
  624. if (mb_strpos($remainder, $key) !== false) {
  625. $county = $countyMap[$key];
  626. $result = [
  627. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  628. 'city' => ['label' => $county['city_label'], 'value' => $county['city_value']]
  629. ];
  630. $cache[$originalStr] = $result;
  631. return $result;
  632. }
  633. }
  634. // 5. 仅返回省份信息
  635. $result = [
  636. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  637. 'city' => ['label' => '', 'value' => '']
  638. ];
  639. $cache[$originalStr] = $result;
  640. return $result;
  641. }
  642. //带转换数据
  643. private function constructAddress3() {
  644. $special = ["710000", "810000", "820000"];
  645. $address2Data = config("address");
  646. $extra_data = [];
  647. foreach ($address2Data as $value){
  648. if(in_array($value['value'], $special)){
  649. $extra_data[] = $value;
  650. }
  651. }
  652. // 1. 加载新数据结构
  653. $address2Data = config("address2");
  654. $address2Data = json_decode($address2Data, true);
  655. // 2. 转换数据结构为旧格式
  656. $addressData = [];
  657. foreach ($address2Data as $province) {
  658. $provinceEntry = [
  659. 'value' => $province['code'],
  660. 'label' => $province['name'],
  661. 'children' => []
  662. ];
  663. if(! isset($province['city'])) continue;
  664. foreach ($province['city'] as $city) {
  665. $cityEntry = [
  666. 'value' => $city['code'],
  667. 'label' => $city['name'],
  668. 'children' => []
  669. ];
  670. foreach ($city['area'] as $area) {
  671. $cityEntry['children'][] = [
  672. 'value' => $area['code'],
  673. 'label' => $area['name']
  674. ];
  675. }
  676. $provinceEntry['children'][] = $cityEntry;
  677. }
  678. $addressData[] = $provinceEntry;
  679. }
  680. $addressData = array_merge_recursive($addressData, $extra_data);
  681. echo json_encode($addressData);die;
  682. $provinceMap = [];
  683. $cityMap = [];
  684. $countyMap = []; // 新增区县映射表
  685. // 添加直辖市特殊处理
  686. $municipalities = [
  687. '110000' => ['北京', '北京市'],
  688. '120000' => ['天津', '天津市'],
  689. '310000' => ['上海', '上海市'],
  690. '500000' => ['重庆', '重庆市']
  691. ];
  692. // 添加省级简称映射
  693. $provinceAbbr = [
  694. '内蒙古' => '内蒙古自治区',
  695. '新疆' => '新疆维吾尔自治区',
  696. '广西' => '广西壮族自治区',
  697. '宁夏' => '宁夏回族自治区',
  698. '西藏' => '西藏自治区'
  699. ];
  700. foreach ($addressData as $province) {
  701. $pValue = $province['value'];
  702. $pLabel = $province['label'];
  703. // 添加省份全称和简称
  704. $shortProvince = preg_replace('/(省|市|自治区|特别行政区)$/u', '', $pLabel);
  705. $provinceMap[$pLabel] = ['label' => $pLabel, 'value' => $pValue];
  706. $provinceMap[$shortProvince] = ['label' => $pLabel, 'value' => $pValue];
  707. $provinceMap[$pValue] = ['label' => $pLabel, 'value' => $pValue]; // 新增:通过编码直接访问
  708. // 添加省级简称
  709. if (isset($provinceAbbr[$shortProvince])) {
  710. $provinceMap[$shortProvince] = ['label' => $pLabel, 'value' => $pValue];
  711. }
  712. // 处理直辖市
  713. if (isset($municipalities[$pValue])) {
  714. $cityLabel = $municipalities[$pValue][1];
  715. $cityMap[$cityLabel] = $cityMap[$municipalities[$pValue][0]] = [
  716. 'label' => $cityLabel,
  717. 'value' => $pValue,
  718. 'province' => $pValue
  719. ];
  720. // 添加直辖市区县映射
  721. foreach ($province['children'][0]['children'] as $district) {
  722. $dLabel = $district['label'];
  723. $countyMap[$dLabel] = [
  724. 'city_label' => $cityLabel,
  725. 'city_value' => $pValue,
  726. 'province_value' => $pValue
  727. ];
  728. // 添加区县简称(去掉"区"字)
  729. $shortDistrict = preg_replace('/区$/', '', $dLabel);
  730. if ($shortDistrict !== $dLabel) {
  731. $countyMap[$shortDistrict] = $countyMap[$dLabel];
  732. }
  733. }
  734. continue;
  735. }
  736. // 处理普通城市和区县
  737. foreach ($province['children'] as $city) {
  738. $cValue = $city['value'];
  739. $cLabel = $city['label'];
  740. // 添加城市全称和简称
  741. $shortCity = preg_replace('/市$/', '', $cLabel);
  742. $cityMap[$cLabel] = [
  743. 'label' => $cLabel,
  744. 'value' => $cValue,
  745. 'province' => $pValue
  746. ];
  747. $cityMap[$shortCity] = [
  748. 'label' => $cLabel,
  749. 'value' => $cValue,
  750. 'province' => $pValue
  751. ];
  752. // 添加自治州特殊处理(如恩施)
  753. if (strpos($cLabel, '自治州') !== false) {
  754. $autonomousShort = str_replace(['自治州', '土家族', '苗族', '壮族'], '', $cLabel);
  755. $cityMap[$autonomousShort] = [
  756. 'label' => $cLabel,
  757. 'value' => $cValue,
  758. 'province' => $pValue
  759. ];
  760. }
  761. // 添加城市常见简称(特殊处理)
  762. $specialAbbr = [
  763. '成都' => '成都市',
  764. '杭州' => '杭州市',
  765. '广州' => '广州市',
  766. '深圳' => '深圳市',
  767. '武汉' => '武汉市',
  768. '南京' => '南京市',
  769. '苏州' => '苏州市',
  770. '宁波' => '宁波市',
  771. '青岛' => '青岛市'
  772. ];
  773. if (isset($specialAbbr[$shortCity])) {
  774. $cityMap[$shortCity] = [
  775. 'label' => $specialAbbr[$shortCity],
  776. 'value' => $cValue,
  777. 'province' => $pValue
  778. ];
  779. }
  780. // 添加区县映射
  781. if (isset($city['children'])) {
  782. foreach ($city['children'] as $county) {
  783. $countyLabel = $county['label'];
  784. $countyMap[$countyLabel] = [
  785. 'city_label' => $cLabel,
  786. 'city_value' => $cValue,
  787. 'province_value' => $pValue
  788. ];
  789. // 添加区县简称(去掉"区"/"县"字)
  790. $shortCounty = preg_replace('/(区|县|市)$/u', '', $countyLabel);
  791. if ($shortCounty !== $countyLabel) {
  792. $countyMap[$shortCounty] = $countyMap[$countyLabel];
  793. }
  794. }
  795. }
  796. }
  797. }
  798. return [$provinceMap, $cityMap, $countyMap]; // 返回三个映射表
  799. }
  800. private function constructAddress2(){
  801. $addressData = config('address');
  802. $provinceMap = [];
  803. $cityMap = [];
  804. // 添加直辖市特殊处理
  805. $municipalities = [
  806. '110000' => ['北京', '北京市'],
  807. '120000' => ['天津', '天津市'],
  808. '310000' => ['上海', '上海市'],
  809. '500000' => ['重庆', '重庆市']
  810. ];
  811. // 添加省级简称映射
  812. $provinceAbbr = [
  813. '内蒙古' => '内蒙古自治区',
  814. '新疆' => '新疆维吾尔自治区',
  815. '广西' => '广西壮族自治区',
  816. '宁夏' => '宁夏回族自治区',
  817. '西藏' => '西藏自治区'
  818. ];
  819. foreach ($addressData as $province) {
  820. $pValue = $province['value'];
  821. $pLabel = $province['label'];
  822. // 添加省份全称和简称
  823. $shortProvince = preg_replace('/(省|市|自治区|特别行政区)$/u', '', $pLabel);
  824. $provinceMap[$pLabel] = ['label' => $pLabel, 'value' => $pValue];
  825. $provinceMap[$shortProvince] = ['label' => $pLabel, 'value' => $pValue];
  826. // 添加省级简称
  827. if (isset($provinceAbbr[$shortProvince])) {
  828. $provinceMap[$shortProvince] = ['label' => $pLabel, 'value' => $pValue];
  829. }
  830. // 处理直辖市
  831. if (isset($municipalities[$pValue])) {
  832. $cityLabel = $municipalities[$pValue][1];
  833. $cityMap[$cityLabel] = $cityMap[$municipalities[$pValue][0]] = [
  834. 'label' => $cityLabel,
  835. 'value' => $pValue,
  836. 'province' => $pValue
  837. ];
  838. continue;
  839. }
  840. // 处理普通城市
  841. foreach ($province['children'] as $city) {
  842. $cValue = $city['value'];
  843. $cLabel = $city['label'];
  844. // 添加城市全称和简称
  845. $shortCity = preg_replace('/市$/', '', $cLabel);
  846. $cityMap[$cLabel] = [
  847. 'label' => $cLabel,
  848. 'value' => $cValue,
  849. 'province' => $pValue
  850. ];
  851. $cityMap[$shortCity] = [
  852. 'label' => $cLabel,
  853. 'value' => $cValue,
  854. 'province' => $pValue
  855. ];
  856. // 添加城市常见简称(特殊处理)
  857. $specialAbbr = [
  858. '成都' => '成都市',
  859. '杭州' => '杭州市',
  860. '广州' => '广州市',
  861. '深圳' => '深圳市',
  862. '武汉' => '武汉市',
  863. '南京' => '南京市'
  864. ];
  865. if (isset($specialAbbr[$shortCity])) {
  866. $cityMap[$shortCity] = [
  867. 'label' => $specialAbbr[$shortCity],
  868. 'value' => $cValue,
  869. 'province' => $pValue
  870. ];
  871. }
  872. }
  873. }
  874. return [$provinceMap, $cityMap];
  875. }
  876. function parseAddress2($str, $provinceMap, $cityMap) {
  877. static $cache = [];
  878. if (isset($cache[$str])) return $cache[$str];
  879. $str = str_replace(['·', ' ', '-'], '', trim($str));
  880. // 1. 处理直辖市简称
  881. $municipalityShort = ['京', '沪', '津', '渝'];
  882. $municipalityMap = [
  883. '京' => '北京市',
  884. '沪' => '上海市',
  885. '津' => '天津市',
  886. '渝' => '重庆市'
  887. ];
  888. if (in_array(mb_substr($str, 0, 1), $municipalityShort)) {
  889. $cityName = $municipalityMap[mb_substr($str, 0, 1)];
  890. $city = $cityMap[$cityName] ?? null;
  891. if ($city) {
  892. $result = [
  893. 'province' => ['label' => $city['label'], 'value' => $city['province']],
  894. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  895. ];
  896. $cache[$str] = $result;
  897. return $result;
  898. }
  899. }
  900. // 2. 完整字符串匹配城市(加强版)
  901. if (isset($cityMap[$str])) {
  902. $city = $cityMap[$str];
  903. $province = $provinceMap[$city['province']] ?? null;
  904. $result = [
  905. 'province' => $province ? ['label' => $province['label'], 'value' => $province['value']] : ['label' => '', 'value' => ''],
  906. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  907. ];
  908. $cache[$str] = $result;
  909. return $result;
  910. }
  911. // 3. 优先匹配3字省份(如内蒙古)
  912. if (mb_strlen($str) >= 3) {
  913. $prefix = mb_substr($str, 0, 3);
  914. if (isset($provinceMap[$prefix])) {
  915. return $this->handleMatchedProvince($prefix, mb_substr($str, 3), $provinceMap, $cityMap, $cache, $str);
  916. }
  917. }
  918. // 4. 匹配2字省份
  919. if (mb_strlen($str) >= 2) {
  920. $prefix = mb_substr($str, 0, 2);
  921. if (isset($provinceMap[$prefix])) {
  922. return $this->handleMatchedProvince($prefix, mb_substr($str, 2), $provinceMap, $cityMap, $cache, $str);
  923. }
  924. }
  925. // 5. 城市关键词扫描(加强版)
  926. $cityKeys = array_keys($cityMap);
  927. usort($cityKeys, fn($a, $b) => mb_strlen($b) - mb_strlen($a));
  928. foreach ($cityKeys as $key) {
  929. if (mb_strpos($str, $key) !== false) {
  930. $city = $cityMap[$key];
  931. $province = $provinceMap[$city['province']] ?? null;
  932. // 特殊处理:当匹配到城市时,尝试找回省份
  933. if (!$province) {
  934. $province = $provinceMap[$city['province']] ?? ['label' => '', 'value' => ''];
  935. }
  936. $result = [
  937. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  938. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  939. ];
  940. $cache[$str] = $result;
  941. return $result;
  942. }
  943. }
  944. // 6. 最终匹配失败
  945. $result = [
  946. 'province' => ['label' => '', 'value' => ''],
  947. 'city' => ['label' => '', 'value' => '']
  948. ];
  949. $cache[$str] = $result;
  950. return $result;
  951. }
  952. // 优化省份匹配后的处理
  953. function handleMatchedProvince2($provinceKey, $remainder, $provinceMap, $cityMap, &$cache, $originalStr) {
  954. $province = $provinceMap[$provinceKey];
  955. // 直辖市特殊处理
  956. $municipalities = ['110000', '120000', '310000', '500000'];
  957. if (in_array($province['value'], $municipalities)) {
  958. $city = $cityMap[$province['label']] ?? null;
  959. if ($city) {
  960. $result = [
  961. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  962. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  963. ];
  964. $cache[$originalStr] = $result;
  965. return $result;
  966. }
  967. }
  968. // 尝试匹配剩余部分
  969. if ($remainder !== '') {
  970. // 先尝试完整匹配
  971. if (isset($cityMap[$remainder])) {
  972. $city = $cityMap[$remainder];
  973. $result = [
  974. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  975. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  976. ];
  977. $cache[$originalStr] = $result;
  978. return $result;
  979. }
  980. // 再尝试关键词扫描
  981. $cityKeys = array_keys($cityMap);
  982. usort($cityKeys, fn($a, $b) => mb_strlen($b) - mb_strlen($a));
  983. foreach ($cityKeys as $key) {
  984. if (mb_strpos($remainder, $key) !== false) {
  985. $city = $cityMap[$key];
  986. $result = [
  987. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  988. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  989. ];
  990. $cache[$originalStr] = $result;
  991. return $result;
  992. }
  993. }
  994. }
  995. // 仅返回省份信息
  996. $result = [
  997. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  998. 'city' => ['label' => '', 'value' => '']
  999. ];
  1000. $cache[$originalStr] = $result;
  1001. return $result;
  1002. }
  1003. private function constructAddress1(){
  1004. $addressData = config('address');
  1005. // 构建映射表
  1006. $provinceMap = [];
  1007. $cityMap = [];
  1008. // 直辖市特殊处理(直接映射到市)
  1009. $municipalities = [
  1010. '110000' => ['北京', '北京市'],
  1011. '120000' => ['天津', '天津市'],
  1012. '310000' => ['上海', '上海市'],
  1013. '500000' => ['重庆', '重庆市']
  1014. ];
  1015. foreach ($addressData as $province) {
  1016. $pValue = $province['value'];
  1017. $pLabel = $province['label'];
  1018. // 生成省份简称
  1019. $shortProvince = preg_replace('/(省|市|自治区|特别行政区)$/u', '', $pLabel);
  1020. $provinceMap[$pLabel] = ['label' => $pLabel, 'value' => $pValue];
  1021. $provinceMap[$shortProvince] = ['label' => $pLabel, 'value' => $pValue];
  1022. // 处理直辖市(省市同名)
  1023. if (isset($municipalities[$pValue])) {
  1024. $cityLabel = $municipalities[$pValue][1];
  1025. $cityMap[$cityLabel] = $cityMap[$municipalities[$pValue][0]] = [
  1026. 'label' => $cityLabel,
  1027. 'value' => $pValue, // 直辖市使用省级代码
  1028. 'province' => $pValue
  1029. ];
  1030. continue;
  1031. }
  1032. // 处理普通城市
  1033. foreach ($province['children'] as $city) {
  1034. $cValue = $city['value'];
  1035. $cLabel = $city['label'];
  1036. // 生成城市简称
  1037. $shortCity = preg_replace('/市$/', '', $cLabel);
  1038. $cityMap[$cLabel] = [
  1039. 'label' => $cLabel,
  1040. 'value' => $cValue,
  1041. 'province' => $pValue
  1042. ];
  1043. if ($shortCity !== $cLabel) {
  1044. $cityMap[$shortCity] = [
  1045. 'label' => $cLabel,
  1046. 'value' => $cValue,
  1047. 'province' => $pValue
  1048. ];
  1049. }
  1050. }
  1051. }
  1052. return [$provinceMap, $cityMap];
  1053. }
  1054. // 解析函数
  1055. function parseAddress1($str, $provinceMap, $cityMap) {
  1056. static $cache = []; // 结果缓存
  1057. if (isset($cache[$str])) return $cache[$str];
  1058. $str = str_replace(['·', ' '], '', trim($str));
  1059. // 1. 处理带分隔符的格式 (广东-佛山)
  1060. if (preg_match('/[-\s]/', $str)) {
  1061. $parts = preg_split('/[-\s]+/', $str);
  1062. foreach ($parts as $part) {
  1063. if ($result = $this->parseAddress($part, $provinceMap, $cityMap)) {
  1064. $cache[$str] = $result;
  1065. return $result;
  1066. }
  1067. }
  1068. }
  1069. // 2. 完整字符串匹配城市
  1070. if (isset($cityMap[$str])) {
  1071. $city = $cityMap[$str];
  1072. $province = $provinceMap[$city['province']] ?? null;
  1073. $result = [
  1074. 'province' => $province ? ['label' => $province['label'], 'value' => $province['value']] : ['label' => '', 'value' => ''],
  1075. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  1076. ];
  1077. $cache[$str] = $result;
  1078. return $result;
  1079. }
  1080. // 3. 优先匹配3字省份 (内蒙古)
  1081. if (mb_strlen($str) >= 3) {
  1082. $prefix = mb_substr($str, 0, 3);
  1083. if (isset($provinceMap[$prefix])) {
  1084. return $this->handleMatchedProvince($prefix, mb_substr($str, 3), $provinceMap, $cityMap, $cache, $str);
  1085. }
  1086. }
  1087. // 4. 匹配2字省份 (江苏)
  1088. if (mb_strlen($str) >= 2) {
  1089. $prefix = mb_substr($str, 0, 2);
  1090. if (isset($provinceMap[$prefix])) {
  1091. return $this->handleMatchedProvince($prefix, mb_substr($str, 2), $provinceMap, $cityMap, $cache, $str);
  1092. }
  1093. }
  1094. // 5. 城市关键词扫描 (解决"成都双流"类问题)
  1095. $cityKeys = array_keys($cityMap);
  1096. usort($cityKeys, fn($a, $b) => mb_strlen($b) - mb_strlen($a));
  1097. foreach ($cityKeys as $key) {
  1098. if (mb_strpos($str, $key) !== false) {
  1099. $city = $cityMap[$key];
  1100. $province = $provinceMap[$city['province']] ?? null;
  1101. $result = [
  1102. 'province' => $province ? ['label' => $province['label'], 'value' => $province['value']] : ['label' => '', 'value' => ''],
  1103. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  1104. ];
  1105. $cache[$str] = $result;
  1106. return $result;
  1107. }
  1108. }
  1109. // 6. 最终匹配失败
  1110. $result = [
  1111. 'province' => ['label' => '', 'value' => ''],
  1112. 'city' => ['label' => '', 'value' => '']
  1113. ];
  1114. $cache[$str] = $result;
  1115. return $result;
  1116. }
  1117. // 省份匹配后的处理
  1118. function handleMatchedProvince1($provinceKey, $remainder, $provinceMap, $cityMap, &$cache, $originalStr) {
  1119. $province = $provinceMap[$provinceKey];
  1120. // 直辖市特殊处理
  1121. if (isset($provinceMap[$province['label']])) {
  1122. $city = $cityMap[$province['label']] ?? null;
  1123. if ($city) {
  1124. $result = [
  1125. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  1126. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  1127. ];
  1128. $cache[$originalStr] = $result;
  1129. return $result;
  1130. }
  1131. }
  1132. // 尝试匹配剩余部分
  1133. if ($remainder !== '' && isset($cityMap[$remainder])) {
  1134. $city = $cityMap[$remainder];
  1135. $result = [
  1136. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  1137. 'city' => ['label' => $city['label'], 'value' => $city['value']]
  1138. ];
  1139. $cache[$originalStr] = $result;
  1140. return $result;
  1141. }
  1142. // 仅返回省份信息
  1143. $result = [
  1144. 'province' => ['label' => $province['label'], 'value' => $province['value']],
  1145. 'city' => ['label' => '', 'value' => '']
  1146. ];
  1147. $cache[$originalStr] = $result;
  1148. return $result;
  1149. }
  1150. }