CityAreaDao.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\common\dao\store;
  12. use app\common\dao\BaseDao;
  13. use app\common\model\BaseModel;
  14. use app\common\model\store\CityArea;
  15. use think\exception\ValidateException;
  16. class CityAreaDao extends BaseDao
  17. {
  18. protected function getModel(): string
  19. {
  20. return CityArea::class;
  21. }
  22. public function search(array $where)
  23. {
  24. return CityArea::getDB()->when(isset($where['pid']) && $where['pid'] !== '', function ($query) use ($where) {
  25. $query->where('parent_id', $where['pid']);
  26. })->when(isset($where['address']) && $where['address'] !== '', function ($query) use ($where) {
  27. $address = explode('/', trim($where['address'], '/'));
  28. $p = array_shift($address);
  29. $_p = $p;
  30. if (mb_strlen($p) - 1 === mb_strpos($p, '市')) {
  31. $p = mb_substr($p, 0, -1);
  32. } elseif (mb_strlen($p) - 1 === mb_strpos($p, '省')) {
  33. $p = mb_substr($p, 0, -1);
  34. } elseif (mb_strlen($p) - 3 === mb_strpos($p, '自治区')) {
  35. $p = mb_substr($p, 0, -3);
  36. }
  37. $pcity = $this->search([])->where('name', $p)->find();
  38. if (!$pcity) $pcity = $this->search([])->where('name', $_p)->find();
  39. if (!$pcity) throw new ValidateException('获取地址失败'.$_p);
  40. $street = array_pop($address);
  41. if ($pcity) {
  42. $path = '/' . $pcity->id . '/';
  43. $query->whereLike('path', "/{$pcity->id}/%");
  44. foreach ($address as $item) {
  45. $id = $this->search([])->whereLike('path', $path . '%')->where('name', $item)->value('id');
  46. if ($id) {
  47. $path .= $id . '/';
  48. } else {
  49. break;
  50. }
  51. }
  52. }
  53. $query->whereLike('path', $path . '%')->where('name', $street);
  54. });
  55. }
  56. /**
  57. * 获取城市列表
  58. *
  59. * 本函数用于根据给定的城市区域对象,获取该城市区域的所有父级城市直到根城市的一个列表。
  60. * 这个功能适用于需要展示城市层级关系的场景,比如导航菜单或选择框。
  61. *
  62. * @param CityArea $city 城市区域对象,包含城市区域的信息。
  63. * @return array 返回一个包含城市区域对象的数组,从根城市到给定城市的父级城市。
  64. */
  65. public function getCityList(CityArea $city)
  66. {
  67. // 如果城市区域没有父级ID,则说明它是根城市,直接返回该城市自身
  68. if (!$city->parent_id) return [$city];
  69. // 通过查询找到给定城市的所有父级城市,路径用'/'分隔
  70. $lst = $this->search([])->where('id', 'in', explode('/', trim($city->path, '/')))->order('id ASC')->select();
  71. // 将给定的城市对象添加到结果列表末尾,确保列表以给定城市结尾
  72. $lst[] = $city;
  73. // 返回包含所有父级城市和给定城市的列表
  74. return $lst;
  75. }
  76. }