SystemStore.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <?php
  2. namespace app\models\system;
  3. use crmeb\traits\ModelTrait;
  4. use crmeb\basic\BaseModel;
  5. /**
  6. * 门店自提 model
  7. * Class SystemStore
  8. * @package app\model\system
  9. */
  10. class SystemStore extends BaseModel
  11. {
  12. const EARTH_RADIUS = 6371;
  13. use ModelTrait;
  14. /**
  15. * 数据表主键
  16. * @var string
  17. */
  18. protected $pk = 'id';
  19. /**
  20. * 模型名称
  21. * @var string
  22. */
  23. protected $name = 'system_store';
  24. public static function getLatlngAttr($value, $data)
  25. {
  26. return $data['latitude'] . ',' . $data['longitude'];
  27. }
  28. public static function verificWhere()
  29. {
  30. return self::where('is_show', 1)->where('is_del', 0);
  31. }
  32. /**
  33. * 获取门店信息
  34. * @param int $id
  35. * @param string $felid
  36. * @return array|mixed|null|string|\think\Model
  37. * @throws \think\db\exception\DataNotFoundException
  38. * @throws \think\db\exception\DbException
  39. * @throws \think\db\exception\ModelNotFoundException
  40. */
  41. public static function getStoreDispose($id = 0, $felid = '')
  42. {
  43. if ($id)
  44. $storeInfo = self::verificWhere()->where('id', $id)->find();
  45. else
  46. $storeInfo = self::verificWhere()->find();
  47. if ($storeInfo) {
  48. $storeInfo['latlng'] = self::getLatlngAttr(null, $storeInfo);
  49. $storeInfo['valid_time'] = $storeInfo['valid_time'] ? explode(' - ', $storeInfo['valid_time']) : [];
  50. $storeInfo['_valid_time'] = str_replace('-', '/', ($storeInfo['valid_time'][0] ?? '') . ' ~ ' . ($storeInfo['valid_time'][1] ?? ""));
  51. $storeInfo['day_time'] = $storeInfo['day_time'] ? str_replace(' - ', ' ~ ', $storeInfo['day_time']) : [];
  52. $storeInfo['_detailed_address'] = $storeInfo['address'] . ' ' . $storeInfo['detailed_address'];
  53. $storeInfo['address'] = $storeInfo['address'] ? explode(',', $storeInfo['address']) : [];
  54. if ($felid) return $storeInfo[$felid] ?? '';
  55. }
  56. return $storeInfo;
  57. }
  58. /**
  59. * 门店列表
  60. * @return mixed
  61. */
  62. // public static function lst()
  63. // {
  64. // $model = new self;
  65. // $model = $model->where('is_show', 1);
  66. // $model = $model->where('is_del', 0);
  67. // $model = $model->order('id DESC');
  68. // return $model->select();
  69. // }
  70. /**
  71. * 计算某个经纬度的周围某段距离的正方形的四个点
  72. *
  73. * @param lng float 经度
  74. * @param lat float 纬度
  75. * @param distance float 该点所在圆的半径,该圆与此正方形内切,默认值为2.5千米
  76. * @return array 正方形的四个点的经纬度坐标
  77. */
  78. public static function returnSquarePoint($lng, $lat, $distance = 200)
  79. {
  80. $dlng = 2 * asin(sin($distance / (2 * self::EARTH_RADIUS)) / cos(deg2rad($lat)));
  81. $dlng = rad2deg($dlng);
  82. $dlat = rad2deg($distance / self::EARTH_RADIUS);
  83. return [
  84. 'left_top' => [
  85. 'lat' => $lat + $dlat,
  86. 'lng' => $lng - $dlng,
  87. ],
  88. 'right_top' => [
  89. 'lat' => $lat + $dlat,
  90. 'lng' => $lng + $dlng
  91. ],
  92. 'left_bottom' => [
  93. 'lat' => $lat - $dlat,
  94. 'lng' => $lng - $dlng
  95. ],
  96. 'right_bottom' => [
  97. 'lat' => $lat - $dlat,
  98. 'lng' => $lng + $dlng
  99. ]
  100. ];
  101. }
  102. /*
  103. 设置where条件
  104. */
  105. public static function nearbyWhere($model = null, $latitude = 0, $longitude = 0)
  106. {
  107. if (!is_object($model)) {
  108. $latitude = $model;
  109. $model = new self();
  110. $longitude = $latitude;
  111. }
  112. $field = "(round(6367000 * 2 * asin(sqrt(pow(sin(((latitude * pi()) / 180 - ({$latitude} * pi()) / 180) / 2), 2) + cos(({$latitude} * pi()) / 180) * cos((latitude * pi()) / 180) * pow(sin(((longitude * pi()) / 180 - ({$longitude} * pi()) / 180) / 2), 2))))) AS distance";
  113. $model->field($field);
  114. return $model;
  115. }
  116. /**
  117. * 获取排序sql
  118. * @param $latitude
  119. * @param $longitude
  120. * @return mixed
  121. */
  122. public static function distanceSql($latitude, $longitude)
  123. {
  124. $field = "(round(6367000 * 2 * asin(sqrt(pow(sin(((latitude * pi()) / 180 - ({$latitude} * pi()) / 180) / 2), 2) + cos(({$latitude} * pi()) / 180) * cos((latitude * pi()) / 180) * pow(sin(((longitude * pi()) / 180 - ({$longitude} * pi()) / 180) / 2), 2))))) AS distance";
  125. return $field;
  126. }
  127. /**
  128. * 门店列表
  129. * @return mixed
  130. */
  131. public static function lst($latitude, $longitude, $page, $limit)
  132. {
  133. $model = new self();
  134. $model = $model->where('is_del', 0);
  135. $model = $model->where('is_show',1);
  136. if ($latitude && $longitude) {
  137. $model = $model->field(['*', self::distanceSql($latitude, $longitude)])->order('distance asc');
  138. }
  139. $list = $model->page((int)$page, (int)$limit)
  140. ->select()
  141. ->hidden(['is_show', 'is_del'])
  142. ->toArray();
  143. if ($latitude && $longitude) {
  144. foreach ($list as &$value) {
  145. //计算距离
  146. $value['distance'] = sqrt((pow((($latitude - $value['latitude']) * 111000), 2)) + (pow((($longitude - $value['longitude']) * 111000), 2)));
  147. //转换单位
  148. $value['range'] = bcdiv($value['distance'], 1000, 1);
  149. }
  150. // $distanceKey = array_column($list, 'distance');
  151. // array_multisort($distanceKey, SORT_ASC, $list);
  152. }
  153. return $list;
  154. }
  155. }