cxfoot/modules/api/models/StoreForm.php
2023-10-27 14:25:12 +08:00

401 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* @author Any
* @description KISS
* @date 2020-12-2
* @version 1.0.0
*
* _____LOG_____
*
*/
namespace app\modules\api\models;
use function AlibabaCloud\Client\value;
use app\components\FlashStorage;
use app\components\SiteHelper;
use app\components\SysConst;
use app\models\Coach;
use app\models\Goods;
use app\models\GoodsHub;
use app\models\Store;
use app\models\User;
use app\components\auth\AToken;
use app\components\EncryptHelper;
use app\modules\api\components\ApiHelper;
use app\modules\api\components\GetDistance;
use yii\data\Pagination;
class StoreForm extends ApiModel
{
public $limit;//条数
public $page; //页数
public $pageCount; // 总页数
public $store_id;
public $coach_id;
public $cx_mch_id;
public $user_id;
public function rules()
{
return [
[['limit', 'page', 'store_id'], 'integer'],
[['page'], 'default', 'value' => 1],
];
}
/**
* 门店列表
*/
public function search($cityId, $name, $lat, $lng)
{
if (!$this->validate()) {
return $this->getModelError();
}
/*if (!is_numeric($lat) || !is_numeric($lng)) {
return $this->apiReturnError('位置信息错误');
}
if (empty($lat) || empty($lng)) {
return $this->apiReturnError('位置信息不能为空');
}*/
$where = ['status' => 1, '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,location_detail,lat,lng,begin_time,end_time,status');
$count_query = clone $query;
$count = $count_query->count();
if (empty($this->limit)) {
$this->limit = 10;
}
if (empty($this->page)) {
$this->page = 1;
}
/*if (!$this->limit) {
$this->limit = $count;
$this->pageCount = $this->page;
$list = $query->orderBy(['sort' => SORT_DESC])->asArray()->all();
} else {
}*/
$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']);
}
$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
];
}
/**
* 门店信息
* @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,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();
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']);
}
// $coachData = [];
// $coachData = Coach::find()->alias('c')
// ->innerJoin(['rt' => User::tableName()], 'c.user_id=rt.id')
// ->select('c.id as coach_id,c.title,c.content,c.coach_photo,c.qualification,rt.real_name,c.number,c.desc')
// ->andWhere([
// 'c.store_id' => $this->store_id,
// 'c.is_delete' => 0,
// 'c.status' => 1
// ])
// ->asArray()->all();
// foreach ($coachData as $key => $value) {
// $coachData[$key]['coach_photo'] = empty($value['coach_photo']) ? '' : SiteHelper::getFullUrl($value['coach_photo']);
// $coachData[$key]['qualification'] = empty($value['qualification']) ? '' : SiteHelper::getFullUrl($value['qualification']);
// $coachData[$key]['content'] = str_replace("/upload/0/1/upload/image", \Yii::$app->request->getHostInfo() . "/upload/0/1/upload/image", $coachData[$key]['content']);
// }
// $storeData['content'] = str_replace("/upload/0/1/upload/image", \Yii::$app->request->getHostInfo() . "/upload/0/1/upload/image", $storeData['content']);
// $storeData['coach_data'] = $coachData;
return $this->apiReturnSuccess('ok', $storeData);
}
/**
* 教练信息
*/
public function coachInfo()
{
if (!$this->coach_id) {
return [
'code' => 1,
'msg' => '教练ID不能为空'
];
}
$query = Coach::find()
->select('id,title,content,coach_photo,qualification,number,user_id')
->where(['id' => $this->coach_id, 'status' => 1])->asArray()->one();
if (!$query) {
return $this->apiReturnSuccess('ok', []);
}
$coachArr = User::findOne(['id' => $query['user_id']]);
$query['real_name'] = $coachArr['real_name'];
$query['coach_photo'] = SiteHelper::getFullUrl($query['coach_photo']);
$query['content'] = str_replace("", \Yii::$app->request->getHostInfo() . "/upload/", $query['content']);
return $this->apiReturnSuccess('ok', $query);
}
/**
* 门店选择-绑定门店
* @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)
{
//保留用户购买的门店 有购买的门店 优先显示已购买门店 没有显示距离最近门店
if (empty($lat) || empty($lng)) {
return $this->apiReturnError('位置信息不能为空');
}
$distance_num = 100000; # 距离 米
if ($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])
->select('id,name,province,province_id,city,city_id,region,region_id,location_detail,lat,lng,begin_time,end_time,status')->asArray()->one();
$list['begin_time'] = date('Y-m-d H:i:s', $list['begin_time']);
$list['end_time'] = date('Y-m-d H:i:s', $list['end_time']);
$list['distance'] = GetDistance::getDistance($lat, $lng, $list['lat'], $list['lng']);
$list['distance'] = str_replace('km', '', $list['distance']); // 转成浮点类型去除km
$data = [
'id' => $list['id'],
'name' => $list['name'],
'location_detail' => $list['location_detail'],
'juli' => $list['distance'],
'lat' => $list['lat'],
'lng' => $list['lng']
];
return $this->apiReturnSuccess('ok', $data);
} else {
$record = $this->distance($lat, $lng, $distance_num);
$data = empty($record) ? [] : $record[0];
if ($data) {
$user->store_id = $data['id'];
if (!$user->save()) {
return [
'code' => 1,
'msg' => '附近无门店'
];
}
}
//转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,
'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) 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'] = SiteHelper::getFullUrl($value['cover_pic']);
}
}
return $this->apiReturnSuccess('ok', $goodsArr);
}
}