mirror of https://github.com/4xmen/xshop.git
Merge pull request #45 from CyberAli1989/master
feat: Implement product listing API with caching and sortingpull/49/head
commit
bc60ae2498
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api\Web;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\AdvResource;
|
||||||
|
use App\Http\Resources\CategoryResource;
|
||||||
|
use App\Http\Resources\PostResource;
|
||||||
|
use App\Http\Resources\ProductResource;
|
||||||
|
use App\Http\Resources\SliderResource;
|
||||||
|
use App\Models\Adv;
|
||||||
|
use App\Models\Category;
|
||||||
|
use App\Models\Menu;
|
||||||
|
use App\Models\Post;
|
||||||
|
use App\Models\Product;
|
||||||
|
use App\Models\Slider;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class HomeController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$data = [];
|
||||||
|
$data['menu'] = Menu::with(['items' => function ($query) {
|
||||||
|
$query->select(['id', 'title', 'menuable_id', 'menuable_type', 'kind', 'meta', 'parent', 'sort', 'user_id', 'menu_id']);
|
||||||
|
}])->first(['id', 'name']);
|
||||||
|
$data['slider'] = SliderResource::collection(Slider::take(6)->get());
|
||||||
|
$data['categories'] = CategoryResource::collection(Category::with('products')->whereNull('parent_id')->orderBy('sort')->take(8)->get());
|
||||||
|
$data['adv'] = AdvResource::collection(
|
||||||
|
Adv::query()
|
||||||
|
->where('status', true)
|
||||||
|
->whereColumn('click', '<', 'max_click')
|
||||||
|
->get()
|
||||||
|
);
|
||||||
|
$data['post'] = PostResource::collection(Post::orderByDesc('created_at')->take(8)->get());
|
||||||
|
return success($data);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Api\Web;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Resources\ProductResource;
|
||||||
|
use App\Models\Category;
|
||||||
|
use App\Models\Product;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
class ProductController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
|
||||||
|
$cacheKey = 'products_' . md5($request->getUri());
|
||||||
|
|
||||||
|
$data = Cache::remember($cacheKey, now()->addMinutes(env('CACHE_LIFE_TIME', 10)), function () use ($request) {
|
||||||
|
$product = Product::query();
|
||||||
|
/**
|
||||||
|
* Product Sort by keys
|
||||||
|
*/
|
||||||
|
if (isset($request['sort']) && !is_null($request['sort'])) {
|
||||||
|
if ($request['sort'] === 'new')
|
||||||
|
$product = $product->orderByDesc('created_at');
|
||||||
|
if ($request['sort'] === 'old')
|
||||||
|
$product = $product->orderBy('created_at');
|
||||||
|
if ($request['sort'] === 'most_view')
|
||||||
|
$product = $product->orderByDesc('view');
|
||||||
|
if ($request['sort'] === 'less_view')
|
||||||
|
$product = $product->orderBy('view');
|
||||||
|
if ($request['sort'] === 'most_buy')
|
||||||
|
$product = $product->orderByDesc('sell');
|
||||||
|
if ($request['sort'] === 'less_buy')
|
||||||
|
$product = $product->orderBy('sell');
|
||||||
|
}
|
||||||
|
if (isset($request['category']) && !is_null($request['category']))
|
||||||
|
$product = $product->where('category_id', Category::firstWhere('slug', $request['category'])->id);
|
||||||
|
|
||||||
|
if (isset($request['search']) && !is_null($request['search']))
|
||||||
|
$product = $product->where('name', 'LIKE', "%$request->search%");
|
||||||
|
|
||||||
|
if (isset($request['min_price']) &&
|
||||||
|
isset($request['max_price']) &&
|
||||||
|
!is_null($request['min_price']) &&
|
||||||
|
!is_null($request['max_price'])
|
||||||
|
) {
|
||||||
|
$product = $product->whereBetween('buy_price', [
|
||||||
|
intval($request->min_price),
|
||||||
|
intval($request->max_price)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$request->merge([
|
||||||
|
'loadCategory' => true
|
||||||
|
]);
|
||||||
|
return [
|
||||||
|
'products' => ProductResource::collection($product->paginate($request->input('per_page', 20)))->resource->toArray(),
|
||||||
|
];
|
||||||
|
});
|
||||||
|
return success($data);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use App\Models\Adv;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class AdvResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var $this Adv
|
||||||
|
*/
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'image' => $this->imgUrl,
|
||||||
|
'title' => $this->title,
|
||||||
|
'link' => $this->link,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use App\Models\Category;
|
||||||
|
use App\Models\Product;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
//use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||||
|
|
||||||
|
class CategoryResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource collection into an array.
|
||||||
|
*
|
||||||
|
* @return array<int|string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request, $data = null): array
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var $this Category
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!$request['loadCategory'])
|
||||||
|
$request->merge([
|
||||||
|
'loadCategory' => false
|
||||||
|
]);
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'name' => $this->name,
|
||||||
|
'slug' => $this->slug,
|
||||||
|
'subtitle' => $this->subtitle,
|
||||||
|
'description' => $this->description,
|
||||||
|
'sort' => $this->sort,
|
||||||
|
'image' => $this->image,
|
||||||
|
'bg' => $this->bg,
|
||||||
|
'products' => $this->when($request->input('loadProduct', true), ProductResource::collection($this->products)->additional(['request' => $request['loadCategory']]))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use App\Models\Post;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class PostResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var $this Post
|
||||||
|
*/
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'slug' => $this->slug,
|
||||||
|
'subtitle' => $this->subtitle,
|
||||||
|
'body' => $this->body,
|
||||||
|
'group' => $this->load('groups'),
|
||||||
|
'author' => $this->load('author'),
|
||||||
|
'view' => $this->view,
|
||||||
|
'is_pinned' => $this->is_pinned,
|
||||||
|
'hash' => $this->hash,
|
||||||
|
'like' => $this->like,
|
||||||
|
'dislike' => $this->dislike,
|
||||||
|
'icon' => $this->icon,
|
||||||
|
'created_at' => $this->created_at,
|
||||||
|
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use App\Models\Product;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class ProductResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var $this Product
|
||||||
|
*/
|
||||||
|
if (!$request['loadProduct'])
|
||||||
|
$request->merge([
|
||||||
|
'loadProduct' => false
|
||||||
|
]);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'name' => $this->name,
|
||||||
|
'slug' => $this->slug,
|
||||||
|
'description' => $this->description,
|
||||||
|
'table' => $this->table,
|
||||||
|
'sku' => $this->sku,
|
||||||
|
'virtual' => $this->virtual,
|
||||||
|
'downloadable' => $this->downloadable,
|
||||||
|
'price' => intval($this->price),
|
||||||
|
'buy_price' => $this->buy_price,
|
||||||
|
'average_rating' => floatval($this->average_rating),
|
||||||
|
'view' => $this->view,
|
||||||
|
'category' => $this->when($request->input('loadCategory', true), new CategoryResource($this->category)),
|
||||||
|
'image' => $this->imgUrl()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use App\Models\Slider;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class SliderResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var $this Slider
|
||||||
|
*/
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'body' => $this->body,
|
||||||
|
'image' => $this->imgUrl(),
|
||||||
|
'tag' => $this->tag,
|
||||||
|
'user_id' => $this->user_id,
|
||||||
|
'status' => $this->status,
|
||||||
|
'data' => $this->data,
|
||||||
|
'user' => $this->load('author')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue