CommunityUserController.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. <?php
  2. namespace addons\Community\api\modules\v1\controllers;
  3. use addons\Community\common\models\CommunityGoods;
  4. use addons\Community\common\models\CommunityGoodsSetting;
  5. use addons\Community\common\models\CommunityUser;
  6. use addons\Community\common\service\SettingService;
  7. use api\controllers\OnAuthController;
  8. use common\enums\StatusEnum;
  9. use common\helpers\LocationHelper;
  10. use common\models\goods\GoodsAttr;
  11. use Yii;
  12. class CommunityUserController extends OnAuthController
  13. {
  14. public $modelClass = '';
  15. protected $authOptional = ['get-user-community-list', 'get-nearest-one'];
  16. /**
  17. * @Description: 选择自提点
  18. * @Author: zsan
  19. * @DateTime 2023-02-15 15:34:38
  20. * @return yii\web\Response
  21. */
  22. public function actionCheckCommunityId()
  23. {
  24. $mall_id = $this->mall_id;
  25. $user_id = $this->user_id;
  26. $data = Yii::$app->request->post();
  27. $valid = Yii::$app->services->validate->validate($data, [
  28. [['community_id'], 'integer'],
  29. [['community_id'], 'required', 'message' => '请选择自提点'],
  30. ]);
  31. if ($valid === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  32. $res = CommunityUser::setData([
  33. 'mall_id' => $mall_id, 'user_id' => $user_id, 'community_id' => $data['community_id'], 'is_checked' => StatusEnum::ENABLED
  34. ]);
  35. if ($res === false) return $this->error(CommunityUser::getStaticError());
  36. return $this->success('success');
  37. }
  38. public function actionGetCommunityList()
  39. {
  40. $params = Yii::$app->request->get();
  41. $valid = Yii::$app->services->validate->validate($params, [
  42. [['latitude', 'longitude', 'keyword', 'type'], 'string'],
  43. [['page', 'nearby', 'limit'], 'integer'],
  44. [['attr_ids'], 'safe'],
  45. ]);
  46. if ($valid === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  47. $longitude = $params['longitude'] ?? 0; //经度
  48. $latitude = $params['latitude'] ?? 0; //纬度
  49. if ($longitude && $latitude) {
  50. $page = $params['page'] ?? 1;
  51. $limit = $params['limit'] ?? 10;
  52. $sort = 'distance';
  53. $mall_id = $this->mall_id;
  54. $head_string = '';
  55. $is_has = false;
  56. $nearby = $params['nearby'] ?? 0;
  57. if (isset($params['attr_ids']) && !empty($params['attr_ids'])) {
  58. $params['attr_ids'] = explode(',', $params['attr_ids']);
  59. $is_has = true;
  60. $goods_attr = GoodsAttr::lists([
  61. 'where' => [
  62. ['status' => StatusEnum::ENABLED], ['id' => $params['attr_ids']]
  63. ],
  64. 'select' => 'goods_id'
  65. ]);
  66. $goods_id = array_column($goods_attr, 'goods_id') ?? [];
  67. $goods_setting = CommunityGoodsSetting::lists([
  68. 'where' => [['status' => StatusEnum::ENABLED], ['goods_id' => $goods_id], ['enable' => StatusEnum::ENABLED]],
  69. 'select' => 'goods_id'
  70. ]);
  71. $goods_id = array_column($goods_setting, 'goods_id') ?? [];
  72. $community_goods = CommunityGoods::lists([
  73. 'where' => [['status' => StatusEnum::ENABLED], ['goods_id' => $goods_id]],
  74. 'select' => 'community_id',
  75. ]);
  76. $head_arr = array_column($community_goods, 'community_id');
  77. $head_string = implode(",", $head_arr);
  78. }
  79. $status = StatusEnum::ENABLED;
  80. $setting_service = new SettingService();
  81. $max_distance = $setting_service->getFieldSetting($this->mall_id, 'position_range');
  82. $sql = " SELECT id,`name`,`address`,latitude, longitude, logo, city_id,
  83. round(
  84. 2 * 6378.137 * ASIN(
  85. SQRT(
  86. POW(
  87. SIN(
  88. PI() * ({$longitude} - longitude) / 360
  89. ),
  90. 2
  91. ) + COS(PI() * {$latitude} / 180) * COS(latitude * PI() / 180) * POW(
  92. SIN(
  93. PI() * ({$latitude} - latitude) / 360
  94. ),
  95. 2
  96. )
  97. )
  98. )
  99. ,1) AS distance
  100. FROM `qimall_addons_community_head` WHERE (`mall_id`={$mall_id}) AND (`status`={$status}) ";
  101. if ($is_has) {
  102. if (!$head_string) {
  103. $sql .= "AND FALSE ";
  104. } else {
  105. $sql .= "AND id IN ($head_string) ";
  106. }
  107. }
  108. if ($nearby) $sql .= " HAVING (`distance`<={$max_distance})";
  109. $count_sql = " SELECT id, latitude, longitude, `name`, `address`, city_id,
  110. round(
  111. 2 * 6378.137 * ASIN(
  112. SQRT(
  113. POW(
  114. SIN(
  115. PI() * ({$longitude} - longitude) / 360
  116. ),
  117. 2
  118. ) + COS(PI() * {$latitude} / 180) * COS(latitude * PI() / 180) * POW(
  119. SIN(
  120. PI() * ({$latitude} - latitude) / 360
  121. ),
  122. 2
  123. )
  124. )
  125. )
  126. ,1) AS distance
  127. FROM `qimall_addons_community_head` WHERE (`mall_id`={$mall_id}) AND (`status`={$status}) ";
  128. if ($is_has) {
  129. if (!$head_string) {
  130. $count_sql .= " AND FALSE ";
  131. } else {
  132. $count_sql .= " AND id IN ($head_string) ";
  133. }
  134. }
  135. if (!empty($params['keyword'])) {
  136. if ($params['type'] == 'address') {
  137. $count_sql .= " AND `address` LIKE '%" . $params['keyword'] . "%'";
  138. $sql .= " AND `address` LIKE '%" . $params['keyword'] . "%'";
  139. } else {
  140. $count_sql .= " AND `name` LIKE '%" . $params['keyword'] . "%'";
  141. $sql .= " AND `name` LIKE '%" . $params['keyword'] . "%'";
  142. }
  143. }
  144. if ($nearby) $count_sql .= " HAVING (`distance`<={$max_distance})";
  145. $sql .= " ORDER BY {$sort} asc";
  146. $total_data = \Yii::$app->db->createCommand($count_sql)->queryAll();
  147. $count = count($total_data);
  148. $sql .= " limit " . ($page - 1) * $limit . ",{$limit}";
  149. $list = \Yii::$app->db->createCommand($sql)->queryAll();
  150. if (!empty($list)) {
  151. $location_obj = new LocationHelper();
  152. foreach ($list as &$item) {
  153. $distance = $location_obj->getDistanceByGeo($item['latitude'], $item['longitude'], $latitude, $longitude);
  154. $item['distance'] = bcmul(bcmul($distance, 1000, 4), 1, 1);
  155. }
  156. }
  157. unset($item);
  158. $list_page['list'] = $list;
  159. $list_page['page'] = $page;
  160. $list_page['page_size'] = $limit;
  161. $list_page['count'] = $count;
  162. $list_page['page_count'] = ceil($count / $limit);
  163. } else {
  164. $list_page['list'] = [];
  165. $list_page['page'] = 0;
  166. $list_page['page_size'] = 10;
  167. $list_page['count'] = 0;
  168. $list_page['page_count'] = 0;
  169. }
  170. return $this->success('成功', $list_page);
  171. }
  172. /**
  173. * @Description: 获取用户自提点选择记录
  174. * @Author: zsan
  175. * @DateTime 2023-02-16 19:04:07
  176. * @return yii\web\Response
  177. */
  178. public function actionGetUserCommunityList()
  179. {
  180. $params = Yii::$app->request->get();
  181. $valid = Yii::$app->services->validate->validate($params, [
  182. [['latitude', 'longitude'], 'string'],
  183. [['attr_ids'], 'safe']
  184. ]);
  185. if ($valid === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  186. $mall_id = $this->mall_id;
  187. $user_id = $this->user_id;
  188. if(!$user_id){
  189. return $this->success('成功', ['current'=>[], 'history'=>[]]);
  190. }
  191. $latitude = $params['latitude'] ?? 0;
  192. $longitude = $params['longitude'] ?? 0;
  193. $list = CommunityUser::lists(
  194. [
  195. 'where' => [['mall_id' => $mall_id], ['user_id' => $user_id], ['status' => StatusEnum::ENABLED]],
  196. 'select' => 'id, user_id, community_id',
  197. 'order' => 'is_checked DESC',
  198. 'with' => [
  199. 'community' => function ($query) {
  200. return $query->select('id, longitude, latitude, name, logo, address')
  201. ->andWhere(['status' => StatusEnum::ENABLED]);
  202. }
  203. ]
  204. ]
  205. );
  206. $head_arr = [];
  207. $is_has = false;
  208. if (isset($params['attr_ids']) && !empty($params['attr_ids'])) {
  209. $params['attr_ids'] = explode(',', $params['attr_ids']);
  210. $is_has = true;
  211. $goods_attr = GoodsAttr::lists([
  212. 'where' => [
  213. ['status' => StatusEnum::ENABLED], ['id' => $params['attr_ids']]
  214. ],
  215. 'select' => 'goods_id'
  216. ]);
  217. $goods_id = array_column($goods_attr, 'goods_id') ?? [];
  218. $goods_setting = CommunityGoodsSetting::lists([
  219. 'where' => [['status' => StatusEnum::ENABLED], ['goods_id' => $goods_id], ['enable' => StatusEnum::ENABLED]],
  220. 'select' => 'goods_id'
  221. ]);
  222. $goods_id = array_column($goods_setting, 'goods_id') ?? [];
  223. $community_goods = CommunityGoods::lists([
  224. 'where' => [['status' => StatusEnum::ENABLED], ['goods_id' => $goods_id]],
  225. 'select' => 'community_id',
  226. ]);
  227. $head_arr = array_column($community_goods, 'community_id');
  228. }
  229. $current = [];
  230. $history = [];
  231. $location_obj = new LocationHelper();
  232. $community_info = CommunityGoods::getLatestCommunityOne($mall_id, $user_id);
  233. if(isset($community_info['community'])){
  234. $current = $community_info['community'];
  235. $distance = $location_obj->getDistanceByGeo($current['latitude'], $current['longitude'], $latitude, $longitude);
  236. $current['distance'] = bcmul(bcmul($distance, 1000, 4), 1, 1);
  237. }
  238. foreach ($list as $k => $v) {
  239. if (empty($v['community'])) {
  240. unset($list[$k]);
  241. continue;
  242. }
  243. $distance = $location_obj->getDistanceByGeo($v['community']['latitude'], $v['community']['longitude'], $latitude, $longitude);
  244. $v['community']['distance'] = bcmul(bcmul($distance, 1000, 4), 1, 1);
  245. if ($k > 0) {
  246. if ($is_has) {
  247. if (!in_array($v['community']['id'], $head_arr)) continue;
  248. }
  249. $history[] = $v['community'];
  250. }
  251. }
  252. return $this->success('成功', compact('current', 'history'));
  253. }
  254. public function actionGetNearestOne()
  255. {
  256. $params = Yii::$app->request->get();
  257. $valid = Yii::$app->services->validate->validate($params, [
  258. [['latitude', 'longitude'], 'string'],
  259. ]);
  260. if ($valid === false) return $this->error(Yii::$app->services->validate->getErrorMessage());
  261. $longitude = $params['longitude'] ?? 0; //经度
  262. $latitude = $params['latitude'] ?? 0; //纬度
  263. $mall_id = $this->mall_id;
  264. $user_id = $this->user_id;
  265. $list_page = [];
  266. $list_page['list'] = [];
  267. if(!$user_id){
  268. return $this->success('成功', $list_page);
  269. }
  270. $community_info = CommunityGoods::getLatestCommunityOne($mall_id, $user_id);
  271. if(!$params['latitude'] || !$params['longitude']) return $this->success('成功', $list_page);
  272. $location_obj = new LocationHelper();
  273. if ($community_info) {
  274. $list_page['list'] = array_merge($list_page['list'], $community_info['community'] ?? []);
  275. $distance = $location_obj->getDistanceByGeo($list_page['list']['latitude'], $list_page['list']['longitude'], $latitude, $longitude);
  276. $distance = bcmul(bcmul($distance, 1000, 4), 1, 1);
  277. $list_page['distance'] = $distance;
  278. } else {
  279. $page = 1;
  280. $limit = 1;
  281. $status = StatusEnum::ENABLED;
  282. $sql = " SELECT id,`name`,`address`,latitude, longitude, logo, city_id,
  283. round(
  284. 2 * 6378.137 * ASIN(
  285. SQRT(
  286. POW(
  287. SIN(
  288. PI() * ({$longitude} - longitude) / 360
  289. ),
  290. 2
  291. ) + COS(PI() * {$latitude} / 180) * COS(latitude * PI() / 180) * POW(
  292. SIN(
  293. PI() * ({$latitude} - latitude) / 360
  294. ),
  295. 2
  296. )
  297. )
  298. )
  299. ,1) AS distance
  300. FROM `qimall_addons_community_head` WHERE (`mall_id`={$mall_id}) AND (`status`={$status}) ";
  301. $sql .= " ORDER BY distance asc";
  302. $sql .= " limit " . ($page - 1) * $limit . ",{$limit}";
  303. $list = \Yii::$app->db->createCommand($sql)->queryAll();
  304. $data = [];
  305. if (!empty($list)) {
  306. foreach ($list as $item) {
  307. $distance = $location_obj->getDistanceByGeo($item['latitude'], $item['longitude'], $latitude, $longitude);
  308. $item['distance'] = bcmul(bcmul($distance, 1000, 4), 1, 1);
  309. $data = $item;
  310. break;
  311. }
  312. }
  313. if ($data) {
  314. CommunityUser::setData([
  315. 'mall_id' => $mall_id, 'user_id' => $user_id, 'community_id' => $data['id'], 'is_checked' => StatusEnum::ENABLED
  316. ]);
  317. }
  318. $list_page['list'] = $data;
  319. }
  320. return $this->success('成功', $list_page);
  321. }
  322. }