| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- <?php
- /**
- * 重庆赤晓店信息科技有限公司
- * https://www.chixiaodian.com
- * Copyright (c) 2023 赤店商城 All rights reserved.
- */
- namespace app\modules\client\models\v1;
- use app\constants\OptionSetting;
- use app\models\Banner;
- use app\models\District;
- use app\models\Goods;
- use app\models\Option;
- use app\models\Order;
- use app\models\SaasCategory;
- use app\models\Store;
- use app\plugins\food\models\FoodGoods;
- use app\plugins\food\models\FoodOrder;
- use yii\base\Model;
- use yii\helpers\Json;
- class StoreListForm extends Model
- {
- public $page = 1;
- public $limit = 12;
- // 经度
- public $longitude;
- // 纬度
- public $latitude;
- // 距离
- public $distance;
- // 0:默认排序 1:距离优先 2:好评优先 3:销量优先 4:低价优先 5:高价优先
- public $sort_type;
- // 搜索关键词
- public $keyword;
- // 分类id
- public $common_cat_id;
- // 城市id
- public $city_id;
- // 区县id
- public $district_id;
- // 筛选option信息
- public $option;
- public function rules()
- {
- return [
- [['longitude', 'latitude', 'keyword', 'option'], 'string'],
- [['longitude', 'latitude', 'keyword'], 'trim'],
- [['page', 'limit', 'common_cat_id', 'distance', 'sort_type', 'city_id', 'district_id'], 'integer'],
- [['page'], 'default', 'value' => 1],
- [['limit'], 'default', 'value' => 12],
- ['option', function ($attr, $params) {
- $data = Json::decode($this->option);
- if (!$data) {
- $this->addError($attr, "{$attr}数据格式错误。");
- }
- $this->option = $data;
- }],
- ['option', function ($attr, $params) {
- if (!is_array($this->option)) {
- $this->addError($attr, "{$attr}必须是一个数组。");
- return;
- }
- foreach ($this->option as $key => $opt) {
- if (!isset($opt['name']) || !isset($opt['value'])) {
- $this->addError($attr, "{$attr}[{$key}]['name']或{$attr}[{$key}]['value']不存在。");
- return;
- }
- }
- }],
- ];
- }
- public function list() {
- if (!$this->validate()) {
- return [
- 'code' => 1,
- 'msg' => $this->getErrorSummary(false)[0]
- ];
- }
- $query = Store::find()->where(['is_delete' => 0, 'is_alliance' => 1]);
- if ($this->keyword) {
- $query->andWhere(['like', 'name', $this->keyword]);
- }
- if ($this->common_cat_id > 0) {
- $query->andWhere(['like', 'category_id', $this->common_cat_id]);
- }
- if ($this->city_id) {
- $query->andWhere(['city_id' => $this->city_id]);
- }
- if ($this->district_id) {
- $query->andWhere(['district_id' => $this->district_id]);
- }
- if (is_array($this->option)) {
- foreach ($this->option as $choose) {
- $query->andWhere("JSON_CONTAINS(info,JSON_OBJECT('name',\"{$choose['name']}\"))")
- ->andWhere("JSON_CONTAINS(info, JSON_OBJECT('list',JSON_ARRAY(\"{$choose['value']}\")))");
- }
- }
- //供应链排除独立运行的店铺
- if (\Yii::$app->prod_is_dandianpu()) {
- $filter_store_id = Option::find()->where(['name' => 'self_mini', 'value' => 1])->select('store_id')->column();
- $query->andWhere(['NOT IN', 'id', $filter_store_id]);
- }
- $latitude = $this->latitude ?: 0;
- $longitude = $this->longitude ?: 0;
- $query->select(['id', 'name', 'logo', 'coordinate', 'created_at', 'category_id', 'tags', 'sales', 'rank', 'per_spend', 'address', 'distance' => "acos(cos({$latitude}*pi()/180 )*cos(latitude*pi()/180)*cos({$longitude}*pi()/180 -longitude*pi()/180)+sin({$latitude}*pi()/180 )*sin(latitude*pi()/180))*6370996.81"]);
- // 0:默认排序 1:距离优先 2:好评优先 3:销量优先 4:低价优先 5:高价优先
- if (empty($this->sort_type)) {
- // $list = $query->orderBy('created_at desc')->asArray()->all();
- $list = $query->orderBy('distance asc')->asArray()->all();
- }
- if ($this->sort_type == 2) {
- $list = $query->orderBy('rank desc')->asArray()->all();
- }
- if ($this->sort_type == 3) {
- $list = $query->orderBy('sales desc')->asArray()->all();
- }
- if ($this->sort_type == 4) {
- $list = $query->orderBy('per_spend asc')->asArray()->all();
- }
- if ($this->sort_type == 5) {
- $list = $query->orderBy('per_spend desc')->asArray()->all();
- }
- if (empty($list)) {
- $list = $query->asArray()->all();
- }
- $distance = array();
- if (!empty($this->sort_type)) {
- foreach ($list as $index => $item) {
- $list[$index]['distance'] = -1;
- if (!empty($item['coordinate'])) {
- list($lati, $long) = explode(',', $item['coordinate']);
- if ($long && $this->longitude) {
- $from = [$this->longitude, $this->latitude];
- $to = [$long, $lati];
- $list[$index]['distance'] = $this->get_distance($from, $to, false, 2);
- if ((($list[$index]['distance'] > $this->distance) && $this->distance > 0) || $list[$index]['distance'] == -1){
- unset($list[$index]);
- continue;
- }
- }
- }
- $distance[] = $list[$index]['distance'];
- // if ($list[$index]['distance'] == -1){
- // unset($list[$index]);
- // } else {
- // $distance[] = $list[$index]['distance'];
- // }
- }
- }
- if ($this->sort_type == 1) {
- $list = array_values($list);
- array_multisort($distance, SORT_ASC, $list);
- }
- $data = array_slice($list, ($this->page - 1) * $this->limit, $this->limit);
- foreach ($data as $index => $item) {
- $list[$index]['distance'] = -1;
- $data[$index]['goods_list'] = $this->goods_list($item);
- if ($this->distance($item['distance']) != -1) {
- $data[$index]['distance'] = '距离' . $this->distance($item['distance']);
- } else {
- $data[$index]['distance'] = '';
- }
- $data[$index]['tags'] = !empty($item['tags']) ? Json::decode($item['tags']) : [];
- }
- $res = [
- 'list' => $data,
- 'page_count' => ceil(count($list) / $this->limit),
- 'row_count' => count($list)
- ];
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => $res
- ];
- }
- /**
- * 获取当前定位信息
- */
- private function locationInfo() {
- $tencent_map_key = Option::get('tencent_map_key', 0, 'saas', '')['value'];
- if (get_store_id() > 0) {
- $tencent_map_key = Option::get(OptionSetting::TENCENT_MAP_KEY, get_store_id(), 'pay', Option::get(OptionSetting::TENCENT_MAP_KEY, get_store_id(), 'store', '')['value'] ?: $tencent_map_key)['value'];
- }
- $place_url = 'https://apis.map.qq.com/ws/geocoder/v1/?location=' . $this->latitude . ',' . $this->longitude . '&key=' . $tencent_map_key;
- $json_place = file_get_contents($place_url);
- $place_arr = Json::decode($json_place);
- if ($place_arr && isset($place_arr['result'])) {
- $address = $place_arr['result']['ad_info'];
- $city = District::find()->select('id, name')->where(['name' => $address['city']])->one();
- $district_list = District::find()->select('id, name')->where(['parent_id' => $city['id']])->asArray()->all();
- $data['city'] = $city;
- $data['district_list'] = $district_list;
- $data['address'] = $address;
- $data['detail'] = $place_arr['result']['formatted_addresses']['recommend'];
- return [
- 'code' => 0,
- 'msg' => '定位成功',
- 'data' => $data
- ];
- } else {
- return [
- 'code' => 1,
- 'msg' => '定位失败'
- ];
- }
- }
- public function config() {
- if (!$this->validate()) {
- return [
- 'code' => 1,
- 'msg' => $this->getErrorSummary(false)[0]
- ];
- }
- $location = $this->locationInfo();
- if ($location['code'] > 0) {
- return $location;
- }
- $data = [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => [
- 'location' => $location['data']
- ]
- ];
- $saas_category = SaasCategory::find()->where(['is_delete' => 0])->orderBy('sort DESC')->asArray()->all();
- $category_data = [];
- foreach ($saas_category as $category) {
- $category_data[] = [
- 'cat_num' => Store::find()->where(['is_delete' => 0, 'category_id' => $category['id']])->count(),
- 'common_cat_id' => $category['id'],
- 'cat_name' => $category['name'],
- 'pic' => $category['icon'],
- 'config' => Json::decode($category['option'])
- ];
- }
- $data['data']['search'] = $category_data;
- $data['data']['banner'] = Banner::find()->andWhere(['is_delete' => 0, 'type' => Banner::TYPE_SAAS])->select('pic_url, title, page_url, open_type')->orderBy('sort ASC')->asArray()->all();
- return $data;
- }
- /**
- * 根据起点坐标和终点坐标测距离
- * @param [array] $from [起点坐标(经纬度),例如:array(118.012951,36.810024)]
- * @param [array] $to [终点坐标(经纬度)]
- * @param [bool] $km 是否以公里为单位 false:米 true:公里(千米)
- * @param [int] $decimal 精度 保留小数位数
- * @return [string] 距离数值
- */
- public function get_distance($from, $to, $km = true, $decimal = 2)
- {
- sort($from);
- sort($to);
- $EARTH_RADIUS = 6370.996; // 地球半径系数
- $distance = $EARTH_RADIUS * 2 * asin(sqrt(pow(sin(($from[0] * pi() / 180 - $to[0] * pi() / 180) / 2), 2) + cos($from[0] * pi() / 180) * cos($to[0] * pi() / 180) * pow(sin(($from[1] * pi() / 180 - $to[1] * pi() / 180) / 2), 2))) * 1000;
- if ($km) {
- $distance = $distance / 1000;
- }
- return round($distance, $decimal);
- }
- private static function distance($distance)
- {
- if ($distance == -1) {
- return -1;
- }
- if ($distance > 1000) {
- $distance = round($distance / 1000, 2) . 'km';
- } else {
- if ($distance <= 0) {
- $distance = '0m';
- } else {
- $distance .= 'm';
- }
- }
- return $distance;
- }
- private function goods_list($params){
- if ($params['category_id'] == 1) {
- $goods_list = FoodGoods::find()->where(['store_id' => $params['id'], 'is_delete' => 0])->select(['name', 'JSON_UNQUOTE(JSON_EXTRACT(cover_pic, \'$[0].url\')) as pic', 'price', 'original_price'])->orderBy('virtual_sales desc, sort desc')->limit(6)->asArray()->all();
- } else {
- $goods_list = Goods::find()->where(['store_id' => $params['id'], 'is_delete' => 0, 'status' => 1])->select(['name', 'price', 'original_price', 'cover_pic'])->orderBy('virtual_sales desc, sort desc')->limit(6)->asArray()->all();
- }
- return $goods_list;
- }
- public function sales() {
- // 上月第一天
- // $last_month_first_day = strtotime(date('Y-m-01') . ' -1 month');
- // 上月最后一天
- // $last_month_last_day = strtotime(date('Y-m-01') . ' -1 day');
- // 本月第一天
- $start_time = strtotime(date("Y-m-01"));
- // 当前时间
- $end_time = time();
- $stores = Store::findAll(['is_delete' => 0]);
- if ($stores) {
- foreach ($stores as $store) {
- $cache_key = 'cache_store_sales_num_' . $store->id;
- // 点餐
- if ($store->category_id == 1) {
- $count = FoodOrder::find()->where(['is_pay' => 1, 'store_id' => $store->id])->andWhere(['>=', 'created_at', $start_time])->andWhere(['<=', 'created_at', $end_time])->count();
- cache()->set($cache_key, $count);
- } else {
- $normal_count = Order::find()->where(['is_pay' => 1, 'store_id' => $store->id])->andWhere(['>=', 'created_at', $start_time])->andWhere(['<=', 'created_at', $end_time])->count();
- $scan_count = \app\plugins\scanCodePay\models\Order::find()->where(['is_pay' => 1, 'store_id' => $store->id])->andWhere(['>=', 'created_at', $start_time])->andWhere(['<=', 'created_at', $end_time])->count();
- cache()->set($cache_key, $normal_count + $scan_count);
- }
- // var_dump(cache()->get($cache_key));
- }
- }
- exit();
- }
- }
|