area.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <?php
  2. // 禁止 HTTP 访问脚本文件
  3. PHP_SAPI === 'cli' or die('Can only run in CLI mode.');
  4. new class() {
  5. private $tree = [];
  6. public function __construct()
  7. {
  8. $this->debug($this->initBd())->write();
  9. }
  10. /**
  11. * 初始化百度地址行政数据
  12. * @return void
  13. */
  14. protected function initBd(): array
  15. {
  16. $url = 'https://api.map.baidu.com/api_region_search/v1/?keyword=%E5%85%A8%E5%9B%BD&sub_admin=3&ak=S7I1ewwAVr8r2MI3rnSKeF3R6GTCZiOo&extensions_code=1';
  17. $provs = json_decode(file_get_contents($url), true)['districts'][0]['districts'];
  18. foreach ($provs as &$prov) {
  19. $prov['list'] = $prov['districts'];
  20. foreach ($prov['list'] as &$city) {
  21. $city['list'] = $city['districts'];
  22. foreach ($city['list'] as &$area) {
  23. unset($area['level'], $area['list'], $area['districts']);
  24. }
  25. unset($city['level'], $city['districts']);
  26. }
  27. unset($prov['level'], $prov['districts']);
  28. }
  29. ksort($provs);
  30. return $this->tree = $provs;
  31. }
  32. /**
  33. * 初始化腾讯地址行政
  34. * @param array $data
  35. * @return array
  36. */
  37. protected function initQq(array $data = []): array
  38. {
  39. $url = 'https://apis.map.qq.com/ws/district/v1/list?key=AVDBZ-VXMC6-VD2SU-M7DX2-TGSV7-WVF3U';
  40. foreach (json_decode(file_get_contents($url), true)['result'] as $items) foreach ($items as $item) {
  41. $data[$item['id']] = ['code' => $item['id'], 'name' => $item['fullname'], 'list' => []];
  42. }
  43. ksort($data);
  44. foreach ($data as $item) {
  45. [$k1, $k2, $k3] = str_split($item['code'], 2);
  46. // 整合省份数据
  47. if ($k2 + $k3 == 0) {
  48. $this->tree[$k1] = $item;
  49. }
  50. // 整合城市
  51. if ($k2 > 0 && $k3 == 0) {
  52. $this->tree[$k1]['list'][$k1 . $k2] = $item;
  53. ksort($this->tree[$k1]['list']);
  54. }
  55. // 整合区域
  56. if ($k2 > 0 && $k3 > 0) {
  57. unset($item['list']);
  58. if (!isset($this->tree[$k1]['list'][$k1 . $k2])) {
  59. $this->tree[$k1]['list'][$k1 . $k2] = array_merge($this->tree[$k1], ['list' => []]);
  60. }
  61. $this->tree[$k1]['list'][$k1 . $k2]['list'][$k1 . $k2 . $k3] = $item;
  62. ksort($this->tree[$k1]['list'][$k1 . $k2]['list']);
  63. }
  64. }
  65. return $this->tree;
  66. }
  67. /**
  68. * 打印输出日志
  69. * @param array $data
  70. * @return $this
  71. */
  72. private function debug(array $data)
  73. {
  74. ob_clean();
  75. header('Content-type:application/json');
  76. echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
  77. return $this;
  78. }
  79. /**
  80. * 写入更新文件
  81. * @return bool
  82. */
  83. private function write(): bool
  84. {
  85. $data = [];
  86. $items = array_values($this->tree);
  87. foreach ($items as &$prov) {
  88. $line = [];
  89. $prov['list'] = array_values($prov['list']);
  90. foreach ($prov['list'] as &$city) {
  91. $city['list'] = array_values($city['list']);
  92. $line[] = $city['name'] . ',' . join(',', array_column($city['list'], 'name'));
  93. }
  94. $data[] = $prov['name'] . '$' . join('|', $line);
  95. }
  96. // 数据写入文件
  97. $jsonFile = __DIR__ . '/data.json';
  98. $scriptFile = dirname(__DIR__) . ' /pcasunzips.js';
  99. $jsonContent = json_encode($items, JSON_UNESCAPED_UNICODE);
  100. $scriptContent = str_replace('__STRING__', join('#', $data), <<<EOL
  101. /********************************************************
  102. *** 加载脚本文件 ***
  103. <script src="pcasunzip.js"></script>
  104. *** 省市联动 ***
  105. new PCAS("Province","City")
  106. new PCAS("Province","City","吉林省")
  107. new PCAS("Province","City","吉林省","吉林市")
  108. *** 省市区联动 ***
  109. new PCAS("Province","City","Area")
  110. new PCAS("Province","City","Area","吉林省")
  111. new PCAS("Province","City","Area","吉林省","松原市")
  112. new PCAS("Province","City","Area","吉林省","松原市","宁江区")
  113. 省、市、地区对象取得的值均为实际值。
  114. 注:省、市、地区提示信息选项的值为""(空字符串)
  115. *********************************************************/
  116. SPT = window.SPT || "-省份-";
  117. SCT = window.SCT || "-城市-";
  118. SAT = window.SAT || "-地区-";
  119. SWT = window.SWT || 0; // 提示文字 0:不显示 1:显示
  120. function PCAS() {
  121. this.SelP = document.getElementsByName(arguments[0])[0];
  122. this.SelC = document.getElementsByName(arguments[1])[0];
  123. this.SelA = document.getElementsByName(arguments[2])[0];
  124. this.DefP = this.SelA ? arguments[3] : arguments[2];
  125. this.DefC = this.SelA ? arguments[4] : arguments[3];
  126. this.DefA = this.SelA ? arguments[5] : arguments[4];
  127. if (this.SelP) this.SelP.PCA = this;
  128. if (this.SelC) this.SelC.PCA = this;
  129. if (this.SelA) this.SelA.PCA = this;
  130. if (this.SelP && this.SelC) {
  131. this.SelP.onchange = function () {
  132. PCAS.SetC(this.PCA)
  133. };
  134. if (this.SelA) this.SelC.onchange = function () {
  135. PCAS.SetA(this.PCA)
  136. };
  137. }
  138. PCAS.init(this).SetP(this)
  139. }
  140. PCAS.init = function (PCA) {
  141. PCA.PCAP = [], PCA.PCAC = [], PCA.PCAA = [], PCA.PCAD = "__STRING__";
  142. if (SWT) PCA.PCAD = SPT + "$" + SCT + "," + SAT + "#" + PCA.PCAD;
  143. PCA.PCAD.split("#").forEach(function (VAL1, ID1) {
  144. PCA.PCAP[ID1] = VAL1.split("$")[0], PCA.PCAC[ID1] = [], PCA.PCAA[ID1] = [];
  145. VAL1.split("$")[1].split("|").forEach(function (VAL2, ID2) {
  146. PCA.PCAC[ID1].push((PCA.PCAR = VAL2.split(",")).shift()), PCA.PCAA[ID1][ID2] = PCA.PCAR;
  147. });
  148. });
  149. return this;
  150. };
  151. PCAS.SetP = function (PCA) {
  152. PCA.PCAP.forEach(function (VAL, IDX) {
  153. PCA.PCAT = PCA.PCAV = VAL;
  154. if (PCA.PCAT === SPT) PCA.PCAV = "";
  155. PCA.SelP.options.add(new Option(PCA.PCAT, PCA.PCAV));
  156. if (PCA.DefP === PCA.PCAV) PCA.SelP[IDX].selected = true
  157. }), PCA.SelC ? PCAS.SetC(PCA) : $(PCA.SelP).trigger('change');
  158. };
  159. PCAS.SetC = function (PCA) {
  160. PCA.SelC.length = 0;
  161. PCA.PCAC[PCA.SelP.selectedIndex].forEach(function (VAL, IDX) {
  162. PCA.PCAT = PCA.PCAV = VAL;
  163. if (PCA.PCAT === SCT) PCA.PCAV = "";
  164. PCA.SelC.options.add(new Option(PCA.PCAT, PCA.PCAV));
  165. if (PCA.DefC === PCA.PCAV) PCA.SelC[IDX].selected = true
  166. }), PCA.SelA ? PCAS.SetA(PCA) : $(PCA.SelC).trigger('change');
  167. };
  168. PCAS.SetA = function (PCA) {
  169. PCA.SelA.length = 0;
  170. PCA.PCAA[PCA.SelP.selectedIndex][PCA.SelC.selectedIndex].forEach(function (VAL, IDX) {
  171. PCA.PCAT = PCA.PCAV = VAL;
  172. if (PCA.PCAT === SAT) PCA.PCAV = "";
  173. PCA.SelA.options.add(new Option(PCA.PCAT, PCA.PCAV));
  174. if (PCA.DefA === PCA.PCAV) PCA.SelA[IDX].selected = true
  175. }), $(PCA.SelA).trigger('change')
  176. };
  177. EOL
  178. );
  179. // 写入区域文件
  180. return file_put_contents($scriptFile, $scriptContent) && file_put_contents($jsonFile, $jsonContent);
  181. }
  182. };