Area.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <?php
  2. namespace app\admin\controller\shop;
  3. use app\common\controller\Backend;
  4. use fast\Http;
  5. use think\Db;
  6. /**
  7. * 地区管理
  8. *
  9. * @icon fa fa-circle-o
  10. */
  11. class Area extends Backend
  12. {
  13. /**
  14. * Area模型对象
  15. * @var \app\admin\model\shop\Area
  16. */
  17. protected $model = null;
  18. protected $searchFields = 'id,name';
  19. public function _initialize()
  20. {
  21. parent::_initialize();
  22. $this->model = new \app\admin\model\shop\Area;
  23. $this->view->assign("statusList", $this->model->getStatusList());
  24. }
  25. /**
  26. * 查看
  27. */
  28. public function index()
  29. {
  30. //设置过滤方法
  31. $this->request->filter(['strip_tags', 'trim']);
  32. if ($this->request->isAjax()) {
  33. //如果发送的来源是Selectpage,则转发到Selectpage
  34. if ($this->request->request('keyField')) {
  35. return $this->selectpage();
  36. }
  37. list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  38. $list = $this->model
  39. ->where($where)
  40. ->order($sort, $order)
  41. ->paginate($limit);
  42. $result = array("total" => $list->total(), "rows" => $list->items(), 'initialized' => \app\admin\model\shop\Area::where('id', '>', 0)->find() ? true : false);
  43. return json($result);
  44. }
  45. return $this->view->fetch();
  46. }
  47. /**
  48. * 导入
  49. */
  50. public function import()
  51. {
  52. if (!$this->request->isPost()) {
  53. $this->error('请求错误');
  54. }
  55. $total = \app\admin\model\shop\Area::where('id', '>', 0)->count();
  56. if ($total > 0) {
  57. $this->error("无需执行导入");
  58. }
  59. Db::startTrans();
  60. try {
  61. $this->importDefaultData();
  62. Db::commit();
  63. } catch (\Exception $e) {
  64. Db::rollback();
  65. $this->error($e->getMessage());
  66. }
  67. $this->success("导入成功");
  68. }
  69. /**
  70. * 导入默认地区数据
  71. */
  72. protected function importDefaultData()
  73. {
  74. $sqlFile = ADDON_PATH . 'shop' . DS . 'data' . DS . 'area.sql';
  75. if (is_file($sqlFile)) {
  76. $lines = file($sqlFile);
  77. $templine = '';
  78. foreach ($lines as $line) {
  79. if (substr($line, 0, 2) == '--' || $line == '' || substr($line, 0, 2) == '/*') {
  80. continue;
  81. }
  82. $templine .= $line;
  83. if (substr(trim($line), -1, 1) == ';') {
  84. $templine = str_ireplace('__PREFIX__', config('database.prefix'), $templine);
  85. $templine = str_ireplace('INSERT INTO ', 'INSERT IGNORE INTO ', $templine);
  86. try {
  87. Db::getPdo()->exec($templine);
  88. } catch (\Exception $e) {
  89. //$e->getMessage();
  90. }
  91. $templine = '';
  92. }
  93. }
  94. }
  95. return true;
  96. }
  97. /**
  98. * 更新地区表
  99. */
  100. public function refresh()
  101. {
  102. if (!$this->request->isPost()) {
  103. $this->error('请求错误');
  104. }
  105. $config = get_addon_config('shop');
  106. $amapKey = $config['amap_webapi_key'];
  107. $url = "http://restapi.amap.com/v3/config/district?key={$amapKey}&keywords=&subdistrict=3&extensions=base";
  108. $result = Http::get($url);
  109. $resultArr = json_decode($result, true);
  110. if (isset($resultArr['status']) && $resultArr['status'] == 1) {
  111. Db::startTrans();
  112. try {
  113. $newArr = $oldArr = [];
  114. array_multisort(array_column($resultArr['districts'][0]['districts'], 'adcode'), SORT_ASC, array_column($resultArr['districts'][0]['districts'], 'adcode'), SORT_ASC, $resultArr['districts'][0]['districts']);
  115. foreach ($resultArr['districts'][0]['districts'] as $i => $province) {
  116. list($lng, $lat) = stripos($province['center'], ',') !== false ? explode(',', $province['center']) : ['', ''];
  117. $level1 = [
  118. 'adcode' => $province['adcode'],
  119. 'lng' => $lng,
  120. 'lat' => $lat,
  121. 'level' => 1,
  122. 'label' => '1_' . $province['adcode'] . '_' . $province['name'],
  123. 'name' => $province['name'],
  124. 'pid' => 0,
  125. 'sublist' => []
  126. ];
  127. array_multisort(array_column($province['districts'], 'adcode'), SORT_ASC, array_column($province['districts'], 'adcode'), SORT_ASC, $province['districts']);
  128. foreach ($province['districts'] as $j => $city) {
  129. list($lng, $lat) = stripos($city['center'], ',') !== false ? explode(',', $city['center']) : ['', ''];
  130. $level2 = [
  131. 'adcode' => $city['adcode'],
  132. 'lng' => $lng,
  133. 'lat' => $lat,
  134. 'level' => 2,
  135. 'label' => '2_' . $city['adcode'] . '_' . $city['name'],
  136. 'name' => $city['name'],
  137. 'sublist' => []
  138. ];
  139. array_multisort(array_column($city['districts'], 'adcode'), SORT_ASC, array_column($city['districts'], 'adcode'), SORT_ASC, $city['districts']);
  140. foreach ($city['districts'] as $k => $area) {
  141. list($lng, $lat) = stripos($area['center'], ',') !== false ? explode(',', $area['center']) : ['', ''];
  142. $level3 = [
  143. 'adcode' => $area['adcode'],
  144. 'lng' => $lng,
  145. 'lat' => $lat,
  146. 'level' => 3,
  147. 'label' => '3_' . $area['adcode'] . '_' . $area['name'],
  148. 'name' => $area['name'],
  149. ];
  150. $level2['sublist'][$k] = $level3;
  151. }
  152. $level1['sublist'][$j] = $level2;
  153. }
  154. $newArr[$i] = $level1;
  155. }
  156. $areaList = \think\Db::name('shop_area')->select();
  157. foreach ($areaList as $index => $item) {
  158. $label = $item['level'] . '_' . $item['adcode'] . '_' . $item['name'];
  159. $item['label'] = $label;
  160. $oldArr[$label] = $item;
  161. }
  162. $this->areaUpdate($newArr, $oldArr);
  163. $ids = [];
  164. foreach ($oldArr as $index => $item) {
  165. if (!isset($item['keep'])) {
  166. $ids[] = $item['id'];
  167. }
  168. }
  169. if ($ids) {
  170. //旧的地区需要做删除处理
  171. \app\admin\model\shop\Area::where(['id' => ['in', $ids]])->where('')->delete();
  172. }
  173. Db::commit();
  174. } catch (\Exception $e) {
  175. Db::rollback();
  176. $this->error("更新失败:" . $e->getMessage());
  177. }
  178. $this->success("更新成功");
  179. } else {
  180. if (isset($resultArr['infocode']) && $resultArr['infocode'] == 10001) {
  181. $this->error('请检查配置中高德地图Web服务API密钥是否正确');
  182. } else {
  183. $this->error($resultArr['info'] ?? '发生错误:' . $result);
  184. }
  185. }
  186. return;
  187. }
  188. protected function areaUpdate($newArea, &$oldArea, $parent = 0)
  189. {
  190. static $pinyin;
  191. if (!$pinyin) {
  192. $pinyin = new \Overtrue\Pinyin\Pinyin('Overtrue\Pinyin\MemoryFileDictLoader');
  193. }
  194. $pid = $parent;
  195. $allow = array_flip(['pid', 'level', 'name', 'adcode', 'zipcode', 'lng', 'lat']);
  196. foreach ($newArea as $k => $v) {
  197. $label = $v['label'];
  198. $hasChild = isset($v['sublist']) && $v['sublist'] ? true : false;
  199. $data = array_intersect_key($v, $allow);
  200. $data['pid'] = $pid;
  201. $data['status'] = 'normal';
  202. if (!isset($oldArea[$label])) {
  203. $data['pinyin'] = $pinyin->permalink($data['name'], '');
  204. $data['py'] = $pinyin->abbr($data['name']);
  205. $area = \app\admin\model\shop\Area::create($data, true);
  206. } else {
  207. $area = $oldArea[$label];
  208. if (array_diff_key($data, $area)) {
  209. $data['pinyin'] = $pinyin->permalink($data['name'], '');
  210. $data['py'] = $pinyin->abbr($data['name']);
  211. //更新旧菜单
  212. \app\admin\model\shop\Area::update($data, ['id' => $area['id']]);
  213. }
  214. $oldArea[$label]['keep'] = true;
  215. }
  216. if ($hasChild) {
  217. $this->areaUpdate($v['sublist'], $oldArea, $area['id']);
  218. }
  219. }
  220. }
  221. }