1], ]; } /** * 门店列表 */ public function search($cityId, $name, $lat, $lng) { if (!$this->validate()) { return $this->getModelError(); } $where = ['is_delete' => 0]; if ($cityId) { $where['city_id'] = $cityId; } $query = Store::find()->where($where)->andFilterWhere(['OR', ['LIKE', 'name', $name]]) ->select('id,name,province,province_id,city,city_id,region,region_id,cover_pic,pic_urls,location_detail,lat,lng,begin_time,end_time,status,store_mobile'); $count_query = clone $query; $count = $count_query->count(); if (empty($this->limit)) { $this->limit = 10; } if (empty($this->page)) { $this->page = 1; } $pagination = new Pagination(['pageSize' => $this->limit, 'totalCount' => $count, 'page' => $this->page - 1]); $list = $query->offset($pagination->offset)->limit($pagination->limit)->orderBy(['sort' => SORT_DESC])->asArray()->all(); $this->pageCount = $pagination->pageCount; foreach ($list as $index => $item) { $item['distance'] = ''; if (!empty($lat) && !empty($lng)) { $item['distance'] = GetDistance::getDistance($lat, $lng, $item['lat'], $item['lng']); } $item['cover_pic'] = substr($item['cover_pic'], 0, 7) == 'http://' ? $item['cover_pic'] : SiteHelper::getFullUrl($item['cover_pic']); // $item['cover_pic'] = SiteHelper::getFullUrl($item['cover_pic']); $item['pic_urls'] = $this->fixPicUrls($item['pic_urls']); $list[$index] = $item; } //是否已经全部加载 $end_flag = $this->page >= $pagination->pageCount ? true : false; return [ 'code' => 0, 'msg' => 'ok', 'data' => $list, 'count' => $count, 'page_size' => $this->limit, 'page_count' => $this->pageCount, 'page_no' => $this->page, 'end_flag' => $end_flag ]; } protected function fixPicUrls($pic_urls) { $pic_urls = is_string($pic_urls) && !empty($pic_urls) ? json_decode($pic_urls, true) : $pic_urls; foreach ($pic_urls as $index => $item) { $item = SiteHelper::getFullUrl($item); $pic_urls[$index] = $item; } return $pic_urls; } /** * 门店信息 * @return array|\yii\db\ActiveRecord|null */ public function searchOne() { if (!$this->store_id) { return [ 'code' => 1, 'msg' => '门店ID不能为空' ]; } // b.name as coach_name,b,content as coach_content,b.coach_photo $storeData = Store::find() ->select('id,name,province,store_mobile,province_id,city,city_id,region,region_id,location_detail,lat,lng,begin_time,end_time,content,pic_urls') ->where(['id' => $this->store_id, 'is_delete' => 0, 'status' => 1])->asArray()->one(); $storeData['pic_arr'] = []; if ($storeData['pic_urls']) { $store_pics = json_decode($storeData['pic_urls'], true); foreach ($store_pics as $k => $v) { $storeData['pic_arr'][] = SiteHelper::getFullUrl($v); } unset($storeData['pic_urls']); } $box_list = Box::find()->select('id as box_id,name,money,cover_pic,device')->where(['store_id' => $this->store_id, 'is_delete' => 0, 'status' => 1])->asArray()->all(); foreach ($box_list as $key => $value) { $value['device'] = json_decode($value['device'], true); $value['cover_pic'] = substr($value['cover_pic'], 0, 7) == 'http://' ? $value['cover_pic'] : SiteHelper::getFullUrl($value['cover_pic']); // $value['cover_pic'] = SiteHelper::getFullUrl($value['cover_pic']); $box_list[$key] = $value; } $storeData['box_list'] = $box_list; return $this->apiReturnSuccess('ok', $storeData); } /** * 门店选择-绑定门店 * @return array */ public function storeBinding() { if (empty($this->store_id)) { return $this->apiReturnError('门店ID不能为空'); } $store = Store::findOne(['id' => $this->store_id]); if ($store == null) { return [ 'code' => 1, 'msg' => '门店不存在' ]; } $user = ApiHelper::findOneUser($this->user_id, $this->cx_mch_id); if ($user == null) { return [ 'code' => 1, 'msg' => '用户不存在' ]; } $user->store_id = $this->store_id; if (!$user->save()) return $this->getModelError($user); return [ 'code' => 0, 'msg' => '绑定成功', 'data' => $this->store_id, ]; } /** * 附近的门店 * @param $lat /纬度 * @param $lng /经度 * @return array */ public function storeHome($lat, $lng, $store_id = 0) { //保留用户购买的门店 有购买的门店 优先显示已购买门店 没有显示距离最近门店 $distance_num = 100000; # 距离 米 if (!empty($this->user_id)) { $user = ApiHelper::findOneUser($this->user_id, $this->cx_mch_id); if ($user == null) { return [ 'code' => 1, 'msg' => '用户不存在' ]; } $this->store_id = $user['store_id']; if ($this->store_id) { $list = Store::find()->where(['id' => $this->store_id, 'is_delete' => 0]) ->select('id,name,pic_urls,province,province_id,content,city,city_id,region,region_id,location_detail,lat,lng,begin_time,end_time,status')->asArray()->one(); if (!empty($list)) { $list['begin_time'] = date('Y-m-d ') . $list['begin_time']; $list['end_time'] = date('Y-m-d ') . $list['end_time']; $list['distance'] = GetDistance::getDistance($lat, $lng, $list['lat'], $list['lng']); $list['distance'] = str_replace('km', '', $list['distance']); // 转成浮点类型,去除km $list['pic_urls'] = $this->fixPicUrls($list['pic_urls']); $data = [ 'id' => $list['id'], 'name' => $list['name'], 'content' => $list['content'], 'location_detail' => $list['location_detail'], 'juli' => $list['distance'], 'lat' => $list['lat'], 'lng' => $list['lng'] ]; return $this->apiReturnSuccess('ok', $data); } } if (empty($lat) || empty($lng)) { // 返回默认数据 $list = Store::find()->where(['is_delete' => 0]); if (!empty($store_id)) { $list = $list->andWhere([ 'id' => $store_id, ]); } $list = $list->select('id,name,pic_urls,province,province_id,content,city,city_id,region,region_id,location_detail,lat,lng,begin_time,end_time,status') ->asArray()->one(); $list['begin_time'] = date('Y-m-d ') . $list['begin_time']; $list['end_time'] = date('Y-m-d ') . $list['end_time']; $list['distance'] = GetDistance::getDistance($lat, $lng, $list['lat'], $list['lng']); $list['distance'] = str_replace('km', '', $list['distance']); // 转成浮点类型,去除km $list['pic_urls'] = $this->fixPicUrls($list['pic_urls']); $data = [ 'id' => $list['id'], 'name' => $list['name'], 'content' => $list['content'], 'location_detail' => $list['location_detail'], 'juli' => $list['distance'], 'lat' => $list['lat'], 'lng' => $list['lng'] ]; return $this->apiReturnSuccess('ok', $data); } $record = $this->distance($lat, $lng, $distance_num); $data = empty($record) ? [] : $record[0]; if ($data) { $user->store_id = $data['id']; if (!$user->save()) { //默认门店 门店id 到时候替换 $storeData = Store::findOne(['id' => 11]); $data = [ 'id' => $storeData->id, 'name' => $storeData->name, 'content' => $storeData->content, 'location_detail' => $storeData->location_detail, 'juli' => strval(5), 'lat' => $storeData->lat, 'lng' => $storeData->lng ]; } } //转KM if (isset($data['juli'])) { $data['juli'] = $data['juli'] / 1000; } return $this->apiReturnSuccess('ok', $data); } $storeData = Store::findOne(['id' => 11]); $data = [ 'id' => $storeData->id, 'name' => $storeData->name, 'content' => $storeData->content, 'location_detail' => $storeData->location_detail, 'juli' => strval(5), 'lat' => $storeData->lat, 'lng' => $storeData->lng ]; return $this->apiReturnSuccess('ok', $data); // 获取redis key $redis_name = \Yii::$app->params['cacheKeyPrefix'] . ":api:store:zset"; $redis_lock_name = $redis_name . "_lock_v1"; $get = FlashStorage::getCache($redis_lock_name); // 判断是否需要初始化 if (empty($get)) { // 初始化 $select = Store::find() ->andWhere([ 'is_delete' => 0, ])->select('id,lat,lng')->asArray()->all(); foreach ($select as $key => $val) { try { \Yii::$app->redis->geoadd($redis_name, $val['lng'], $val['lat'], $val['id']); } catch (\Exception $e) { } } FlashStorage::setCache($redis_lock_name, 1, 60 * 60 * 24 * 30); } try { $res = \Yii::$app->redis->georadius($redis_name, $lng, $lat, $distance_num, 'm', 'ASC', 'WITHDIST', 'count', 1); // 没有查找到,则到数据库里再找一次,每天仅一个人能够查找 $redis_lock_day_name = $redis_lock_name . "_" . date('d'); $get = FlashStorage::getCache($redis_lock_day_name); if (empty($res) && empty($get)) { // FlashStorage::setCache($redis_lock_day_name, 1, 60 * 60 * 24); //当前位置经纬度 经度:117.215637 纬度:39.1373367 //表中经纬度字段 经度:longitude 纬度:latitude //查询距离小于10公里的门店 //如果没有 就返回空 $record = $this->distance($lat, $lng, $distance_num); if (!empty($record)) { try { \Yii::$app->redis->geoadd($redis_name, $record[0]['lng'], $record[0]['lat'], $record[0]['id']); } catch (\Exception $e) { } $id = $record[0]['id']; $km = $record[0]['juli'] / 1000; // 删除缓存键 FlashStorage::deleteCache($redis_lock_name); } } else { $id = $res[0][0]; $km = round($res[0][1] / 1000, 2); } if (empty($id)) { $data = []; } else { $find = Store::findOne([ 'id' => $id, ]); $data = [ 'id' => $find->id, 'name' => $find->name, 'location_detail' => $find->location_detail, 'juli' => strval($km), 'lat' => $find['lat'], 'lng' => $find['lng'] ]; } return $this->apiReturnSuccess('ok', $data); } catch (\Exception $e) { return $this->apiReturnError($e->getMessage()); } } /** * 门店距离 */ public function distance($lat, $lng, $distance_num) { $sql = "select * from( SELECT id,`name`,location_detail,lat,lng, ROUND(6378.138*2*ASIN(SQRT(POW(SIN(($lat * PI()/180 - lat * PI()/180)/2),2) + COS($lat * PI()/180) * COS(lat * PI()/180) * POW(SIN(($lng * PI()/180- lng * PI()/180)/2),2))) * 1000) AS juli FROM cx_store where is_delete = 0) as tmp_table_name order by juli limit 1"; $query = (new Store())->find(); $query->sql = $sql; $create = $query->createCommand(); $record = $create->queryAll(); return $record; } /** * 门店服务列表 */ public function storeGoodsList() { $goodsArr = []; $goodsArr = Goods::find()->alias('goods') ->innerJoin(['goodsHub' => GoodsHub::tableName()], 'goods.goods_hub_id=goodsHub.id') ->select('goods.id,goods.price,goods.plugin_sign,goodsHub.name as goods_name,goodsHub.cover_pic,goodsHub.detail') ->andWhere([ 'goods.is_delete' => 0, ]) ->andWhere(['!=', 'goods.plugin_sign', SysConst::$cxPluginSceneMemberMall]) ->asArray()->all(); if ($goodsArr) { foreach ($goodsArr as $key => $value) { $goodsArr[$key]['cover_pic'] = substr($value['cover_pic'], 0, 7) == 'http://' ? $value['cover_pic'] : SiteHelper::getFullUrl($value['cover_pic']); // $goodsArr[$key]['cover_pic'] = SiteHelper::getFullUrl($value['cover_pic']); } } return $this->apiReturnSuccess('ok', $goodsArr); } }