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']) { $k = '%' . $p['keyword'] . '%'; foreach (['model','content'] as $col) { $config['orWhere'][] = [$col, 'like', $k]; } } 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('请补全个人中心的门店位置及电话'); } if(empty($user->is_release)){ $UserOld = UserOld::where('mobile', $user->mobile)->first(); if(!empty($UserOld)){ $user->is_release = 1; $user->save(); }else{ throw new BusinessException('请联系管理员申请发布权限'); } } $data['status'] = 1; $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); $keyword = $request->get('keyword', ''); $category_id = $request->get('category_id'); 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 = " . $status; if (!empty($category_id)) { $sql = $sql." AND category_id = " . $category_id; } if (!empty($keyword)) { $sql = $sql." AND (content LIKE '%".$keyword."%' OR `model` LIKE '%".$keyword."%')"; } $sql = $sql." 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; // 未知类型 } }