Store.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. namespace app\api\model\store;
  3. use app\common\model\store\Store as StoreModel;
  4. use Symfony\Component\HttpFoundation\File\UploadedFile;
  5. use think\Cache;
  6. use think\Db;
  7. /**
  8. * 商家门店模型
  9. */
  10. class Store extends StoreModel
  11. {
  12. /**
  13. * 隐藏字段
  14. */
  15. protected $hidden = [
  16. 'is_delete',
  17. 'app_id',
  18. 'create_time',
  19. 'update_time'
  20. ];
  21. /**
  22. * 获取门店列表
  23. */
  24. public function getList($is_check = null, $longitude = '', $latitude = '', $limit = false, $shop_supplier_id = 0)
  25. {
  26. $model = $this;
  27. // 是否支持自提核销
  28. $is_check && $model = $model->where('is_check', '=', $is_check);
  29. // 商家id
  30. $shop_supplier_id && $model = $model->where('shop_supplier_id', '=', $shop_supplier_id);
  31. // 获取数量
  32. $limit != false && $model = $model->limit($limit);
  33. // 获取门店列表数据
  34. $data = $model->where('is_delete', '=', '0')
  35. ->where('status', '=', '1')
  36. ->order(['sort' => 'asc', 'create_time' => 'desc'])
  37. ->select();
  38. // 根据距离排序
  39. return $this->sortByDistance($data, $longitude, $latitude);
  40. }
  41. /**
  42. * 获取平台门店列表
  43. */
  44. public function getChoiceLists($is_check = null, $longitude = '', $latitude = '', $limit = false, $shop_supplier_id = 0)
  45. {
  46. $cacheKey = "caches:stores:{$shop_supplier_id}_".intval($limit).'_'.md5("{$is_check}_{$latitude}_{$longitude}");
  47. // if($list = \think\facade\Cache::get($cacheKey)){
  48. // return $list;
  49. // }
  50. $model = $this;
  51. // 是否支持自提核销
  52. $is_check && $model = $model->where('is_check', '=', $is_check);
  53. // 商家id
  54. $shop_supplier_id && $model = $model->where('shop_supplier_id', '=', $shop_supplier_id);
  55. // 获取数量
  56. $limit != false && $model = $model->limit($limit);
  57. $sort = ['sort' => 'asc', 'create_time' => 'desc'];
  58. if (!empty($longitude) && !empty($latitude)) {
  59. $fieldSql = "*,".\think\facade\Db::Raw("(6378.138 * 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))) * 1000) as distance");
  60. $sort['distance'] = 'asc';
  61. }else {
  62. $fieldSql = '*';
  63. }
  64. // 获取门店列表数据
  65. $list = $model->with(['logo','supplier'])
  66. ->where('is_delete', '=', '0')
  67. ->where('status', '=', '1')
  68. ->field($fieldSql)
  69. ->order($sort)
  70. ->paginate()
  71. ->each(function ($store, $k){
  72. $store['distance'] = round($store['distance'], 3);
  73. $store['shop_business'] = 0;
  74. $shop_hours = isset($store['shop_hours'])? $store['shop_hours'] : '';
  75. $shop_hours = explode('~', $shop_hours);
  76. $start = isset($shop_hours[0])? $shop_hours[0] : '';
  77. $end = isset($shop_hours[1])? $shop_hours[1] : '';
  78. if($start && date('H:i') >= $start){
  79. if($end && date('H:i') <= $end || empty($end)){
  80. $store['shop_business'] = 1;
  81. }
  82. }
  83. if($store['distance'] > 0){
  84. if ($store['distance'] >= 1000) {
  85. $distance = bcdiv($store['distance'], 1000, 2);
  86. $store['distance_unit'] = $distance . 'km';
  87. } else
  88. $store['distance_unit'] = round($store['distance'], 2) . 'm';
  89. }else{
  90. $store['distance_unit'] = '未知';
  91. }
  92. });
  93. if($list){
  94. //\think\facade\Cache::tag('cache')->set($cacheKey, $list, rand(5, 10));
  95. }
  96. return $list;
  97. }
  98. /**
  99. * 根据距离排序
  100. */
  101. private function sortByDistance(&$data, $longitude, $latitude)
  102. {
  103. // 根据距离排序
  104. $list = $data->isEmpty() ? [] : $data->toArray();
  105. $sortArr = [];
  106. foreach ($list as &$store) {
  107. /* $logo_image_id = isset($store['logo_image_id'])? $store['logo_image_id'] : 0;
  108. $store['logo_image'] = '';
  109. if($logo_image_id){
  110. $store['logo_image'] =
  111. }*/
  112. if (!empty($longitude) && !empty($latitude)) {
  113. // 计算距离
  114. $distance = self::getDistance($longitude, $latitude, $store['longitude'], $store['latitude']);
  115. // 排序列
  116. $sortArr[] = $distance;
  117. $store['distance'] = $distance;
  118. if ($distance >= 1000) {
  119. $distance = bcdiv($distance, 1000, 2);
  120. $store['distance_unit'] = $distance . 'km';
  121. } else
  122. $store['distance_unit'] = $distance . 'm';
  123. } else {
  124. $store['distance'] = '0.00';
  125. $store['distance_unit'] = '未知';
  126. }
  127. }
  128. if (!empty($longitude) && !empty($latitude)) {
  129. // 根据距离排序
  130. array_multisort($sortArr, SORT_ASC, $list);
  131. }
  132. return $list;
  133. }
  134. /**
  135. * 获取两个坐标点的距离
  136. */
  137. private static function getDistance($ulon, $ulat, $slon, $slat)
  138. {
  139. // 地球半径
  140. $R = 6378137;
  141. // 将角度转为狐度
  142. $radLat1 = deg2rad($ulat);
  143. $radLat2 = deg2rad($slat);
  144. $radLng1 = deg2rad($ulon);
  145. $radLng2 = deg2rad($slon);
  146. // 结果
  147. $s = acos(cos($radLat1) * cos($radLat2) * cos($radLng1 - $radLng2) + sin($radLat1) * sin($radLat2)) * $R;
  148. // 精度
  149. $s = round($s * 10000) / 10000;
  150. return round($s);
  151. }
  152. /**
  153. * 根据门店id集获取门店列表
  154. */
  155. public function getListByIds($storeIds)
  156. {
  157. $model = $this;
  158. // 筛选条件
  159. $filter = ['store_id' => ['in', $storeIds]];
  160. if (!empty($storeIds)) {
  161. $model = $model->orderRaw('field(store_id, ' . implode(',', $storeIds) . ')');
  162. }
  163. // 获取商品列表数据
  164. return $model->with(['logo'])
  165. ->where('is_delete', '=', '0')
  166. ->where('status', '=', '1')
  167. ->where($filter)
  168. ->select();
  169. }
  170. }