285 lines
8.5 KiB
PHP
285 lines
8.5 KiB
PHP
<?php
|
|
|
|
namespace app\common\service;
|
|
|
|
use app\common\model\PostMedia;
|
|
use app\common\model\Sku;
|
|
use app\common\model\User;
|
|
use app\common\validate\PostValidate;
|
|
use app\common\traits\crud\CrudServiceTrait;
|
|
use app\common\model\Post;
|
|
use support\exception\BusinessException;
|
|
use support\Redis;
|
|
use support\Request;
|
|
use support\Db;
|
|
|
|
class PostService
|
|
{
|
|
|
|
use CrudServiceTrait;
|
|
|
|
/**
|
|
* 指定当前要操作的模型
|
|
*/
|
|
protected string $modelClass = Post::class;
|
|
|
|
/**
|
|
* 验证器
|
|
*/
|
|
protected $validator = PostValidate::class;
|
|
|
|
/**
|
|
* 获取验证器
|
|
*/
|
|
public function getValidator()
|
|
{
|
|
return new $this->validator;
|
|
}
|
|
|
|
/**
|
|
* 构造 CrudUtil 查询配置
|
|
*/
|
|
protected function buildQueryConfig(Request $request, string $scene = 'default'): array
|
|
{
|
|
$p = $request->all();
|
|
|
|
$config = [];
|
|
$config['model'] = $this->modelClass;
|
|
switch ($scene) {
|
|
case 'default':
|
|
$config['where']['status'] = 1;
|
|
$config['order']['sort'] = 'desc';
|
|
$config['order']['id'] = 'desc';
|
|
break;
|
|
case 'index':
|
|
if (isset($p['category_id']) && $p['category_id']) {
|
|
$config['where']['category_id'] = $p['category_id'];
|
|
}
|
|
if (isset($p['scene']) && $p['scene']=='self') {
|
|
if(!empty($request->user) && !empty($request->user->uid)){
|
|
$config['where']['user_id'] = $request->user->uid;
|
|
}else{
|
|
$config['where']['user_id'] = -1;
|
|
}
|
|
}
|
|
if(isset($p['year']) && $p['year']){
|
|
$from = strtotime($p['year'].'-01-01');
|
|
$to = strtotime($p['year'].'-12-31 23:59:59');
|
|
$config['where']['created_at'] = [
|
|
'between', [$from, $to]
|
|
];
|
|
}
|
|
if (isset($p['keyword']) && $p['keyword']) {
|
|
$config['where']['content'] = ['like', '%'.$p['keyword'].'%'];
|
|
}
|
|
|
|
if (isset($p['status']) && $p['status']) {
|
|
$config['where']['status'] = $p['status'];
|
|
}
|
|
// else{
|
|
// $config['where']['status'] = 1;
|
|
// }
|
|
|
|
if (isset($p['favorite']) && $p['favorite']) {
|
|
$config['order']['favorite'] = 'desc';
|
|
} elseif (isset($p['browse']) && $p['browse']) {
|
|
$config['order']['browse'] = 'desc';
|
|
} else {
|
|
$config['order']['id'] = 'desc';
|
|
}
|
|
break;
|
|
case 'show':
|
|
$config['where']['id'] = $p['id'];
|
|
break;
|
|
case 'store':
|
|
break;
|
|
case 'update':
|
|
$config['where']['id'] = $p['id'];
|
|
break;
|
|
case 'destroy':
|
|
$config['where']['id'] = $p['id'];
|
|
break;
|
|
}
|
|
|
|
return $config;
|
|
}
|
|
|
|
/**
|
|
* 添加前置处理
|
|
*/
|
|
public function beforeServiceStore($data, Request $request)
|
|
{
|
|
$data['user_id'] = $request->user->uid;;
|
|
if(empty($data['sku_id'])){
|
|
throw new BusinessException('未选择关联产品');
|
|
}
|
|
$user = User::where('id', $data['user_id'])->first();
|
|
if(empty($user->latitude) || empty($user->longitude) || empty($user->mobile)){
|
|
throw new BusinessException('请补全个人中心的门店位置及电话');
|
|
}
|
|
$data['status'] = 2;
|
|
$data['latitude'] = $user->latitude;
|
|
$data['longitude'] = $user->longitude;
|
|
$data['location_name'] = $user->location_name;
|
|
$data['shop_name'] = $user->shop_name;
|
|
$media = serialize($data['media']);
|
|
redis::set('PostMedia_'.$data['user_id'],$media,30);
|
|
unset($data['media']);
|
|
|
|
$sku = Sku::where('id',$data['sku_id'])->first();
|
|
$data['category_id'] = $sku->category_id;
|
|
$data['model'] = $sku->model;
|
|
// $latitude = $data['latitude'];
|
|
// $longitude = $data['longitude'];
|
|
// $data['geo'] = `ST_SRID(POINT($latitude, $longitude), 4326)`;
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* 添加后置处理
|
|
*/
|
|
public function afterServiceStore($res)
|
|
{
|
|
$media = redis::get('PostMedia_'.$res['user_id']);
|
|
$media = unserialize($media);
|
|
if(!is_array($media)){
|
|
$media = explode(',',$media);
|
|
}
|
|
foreach ($media as $v) {
|
|
PostMedia::create([
|
|
'post_id' => $res->id,
|
|
'media_type' => $this->getMediaTypeByUrl($v),
|
|
'url' => $v,
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 添加前置处理
|
|
*/
|
|
public function beforeServiceUpdate($data, Request $request)
|
|
{
|
|
// $data['user_id'] = $request->user->uid;;
|
|
// $media = serialize($data['media']);
|
|
// redis::set('PostMedia_'.$data['user_id'],$media,30);
|
|
// unset($data['media']);
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* 添加后置处理
|
|
*/
|
|
public function afterServiceUpdate($res)
|
|
{
|
|
// PostMedia::where('post_id', $res->id)->delete();
|
|
// $media = redis::get('PostMedia_'.$res['user_id']);
|
|
// $media = unserialize($media);
|
|
// foreach ($media as $v) {
|
|
// PostMedia::create([
|
|
// 'post_id' => $res->id,
|
|
// 'media_type' => $this->getMediaTypeByUrl($v['url']),
|
|
// 'url' => $v['url'],
|
|
// ]);
|
|
// }
|
|
}
|
|
|
|
/**
|
|
* 添加前置处理
|
|
*/
|
|
public function beforeServiceShow($data, Request $request)
|
|
{
|
|
$post = Post::find($data['id']);
|
|
if(!$post){
|
|
$post->browse = $post->browse+1;
|
|
$post->save();
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
// /** 分页列表 */
|
|
// public function serviceNearby(Request $request, string $scene = 'index')
|
|
// {
|
|
// $result = $this->cqyProcess(ucfirst($scene), $request);
|
|
// if ($result === false) {
|
|
// $config = $this->buildQueryConfig($request, $scene);
|
|
// $limit = (int)$request->get('size', 15);
|
|
// $page = (int)$request->get('current', 1);
|
|
// $result = $this->logicList($config, $limit, $page);
|
|
// }
|
|
// return $this->postProcess(ucfirst($scene), $result);
|
|
// }
|
|
|
|
/** 分页列表 */
|
|
public function serviceNearby(Request $request, string $scene = 'nearby')
|
|
{
|
|
$lng = $request->get('lng');
|
|
$lat = $request->get('lat');
|
|
$status = $request->get('status', 1);
|
|
|
|
if (!$lng || !$lat) {
|
|
throw new BusinessException('经纬度必传');
|
|
}
|
|
|
|
$sql = "SELECT
|
|
id,
|
|
user_id,
|
|
category_id,
|
|
sku_id,
|
|
location_name,
|
|
content,
|
|
latitude,
|
|
longitude,
|
|
`like`,
|
|
shop_name,
|
|
favorite,
|
|
comment,
|
|
created_at,
|
|
updated_at,
|
|
price,
|
|
age,
|
|
(6371000 * ACOS(
|
|
COS(RADIANS(?)) * COS(RADIANS(latitude)) *
|
|
COS(RADIANS(longitude) - RADIANS(?)) +
|
|
SIN(RADIANS(?)) * SIN(RADIANS(latitude))
|
|
)) AS distance
|
|
FROM post
|
|
WHERE $status
|
|
HAVING distance <= ?
|
|
ORDER BY distance
|
|
LIMIT 50";
|
|
|
|
// 根据场景设置半径
|
|
$radius = $scene === 'nearby' ? 2000000000 : 200000;
|
|
|
|
// $query = Db::select($sql, [
|
|
// 'lat' => $lat,
|
|
// 'lng' => $lng,
|
|
// 'radius' => $radius
|
|
// ]);
|
|
$query = Db::select($sql, [$lat, $lng, $lat, $radius]);
|
|
$result =json_decode(json_encode($query), true);
|
|
return $result;
|
|
}
|
|
|
|
function getMediaTypeByUrl(string $url): int
|
|
{
|
|
// 提取后缀
|
|
$ext = strtolower(pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION));
|
|
|
|
// 图片类型
|
|
$imageExt = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'];
|
|
// 视频类型
|
|
$videoExt = ['mp4', 'mov', 'avi', 'wmv', 'flv', 'mkv'];
|
|
|
|
if (in_array($ext, $imageExt)) {
|
|
return 1; // 图片
|
|
}
|
|
if (in_array($ext, $videoExt)) {
|
|
return 2; // 视频
|
|
}
|
|
|
|
return 0; // 未知类型
|
|
}
|
|
} |